/*
Note:

This file contains classes for inline COLLADA writing. No data are stored, XML code is written directly to file.

Each Collada***Writer contains 3 sorts of methods:
	- Set***(): sets optional attribute values.
	- Add***(): adds an inner value tag. Once a Add***() method is called, no Set***() method can be called.
	- Open***(): opens an inner tag. Once a Open***() method is called, no Set***() method can be called.
	  To call an Add***() afterwards, call the Close() method on the object returned by the called Open***() method.

Notice: these classes do not enforce the COLLADA specification completely. For example, they do not check if the elements
  are written in the right order, nor it checks for the right number of occurences. Please refer to the COLLADA specification
  and call these methods accordingly.
*/

#pragma once

#include "XmlFileWriter.h"
#include "CommonUtils.h"
#include <time.h>

// The list of declarated classes.
class ColladaAccessorWriter;
class ColladaAmbientCoreWriter;
class ColladaAnimationWriter;
class ColladaAnimationClipWriter;
class ColladaAssetWriter;
class ColladaBoolArrayWriter;
class ColladaCameraWriter;
class ColladaContributorWriter;
class ColladaControllerWriter;
class ColladaControlVerticesWriter;
class ColladaDirectionalWriter;
class ColladaEvaluateSceneWriter;
class ColladaExtraWriter;
class ColladaElementWriter;
class ColladaFloatArrayWriter;
class ColladaFormulaWriter;
class ColladaGeometryWriter;
class ColladaIDREFArrayWriter;
class ColladaImagerWriter;
class ColladaInstanceAnimationWriter;
class ColladaInstanceCameraWriter;
class ColladaInstanceControllerWriter;
class ColladaInstanceFormulaWriter;
class ColladaInstanceGeometryWriter;
class ColladaInstanceLightWriter;
class ColladaInstanceNodeWriter;
class ColladaInstanceVisualSceneWriter;
class ColladaIntArrayWriter;
class ColladaJointsWriter;
class ColladaLibraryAnimationClipsWriter;
class ColladaLibraryAnimationsWriter;
class ColladaLibraryCamerasWriter;
class ColladaLibraryControllersWriter;
class ColladaLibraryFormulasWriter;
class ColladaLibraryGeometriesWriter;
class ColladaLibraryLightsWriter;
class ColladaLibraryNodesWriter;
class ColladaLibraryVisualScenesWriter;
class ColladaLightWriter;
class ColladaLinesWriter;
class ColladaLineStripsWriter;
class ColladaMeshWriter;
class ColladaMorphWriter;
class ColladaNameArrayWriter;
class ColladaNewParamWriter;
class ColladaNewParamFXWriter;
class ColladaNodeWriter;
class ColladaOpticsWriter;
class ColladaOrthographicWriter;
class ColladaPerspectiveWriter;
class ColladaPointWriter;
class ColladaPolygonsWriter;
class ColladaPolyListWriter;
class ColladaSamplerWriter;
class ColladaSceneWriter;
class ColladaSetParamFXWriter;
class ColladaSIDREFArrayWriter;
class ColladaSkeletonWriter;
class ColladaSkinWriter;
class ColladaSourceCoreWriter;
class ColladaSplineWriter;
class ColladaSpotWriter;
class ColladaTargetsWriter;
class ColladaTechniqueCoreWriter;
class ColladaTrianglesWriter;
class ColladaTriFansWriter;
class ColladaTriStripsWriter;
class ColladaVertexWeightsWriter;
class ColladaVerticesWriter;
class ColladaVisualSceneWriter;
class ColladaAttachmentWriter;
class ColladaBoxWriter;
class ColladaCapsuleWriter;
class ColladaConvexMeshWriter;
class ColladaCylinderWriter;
class ColladaForceFieldWriter;
class ColladaInstanceForceFieldWriter;
class ColladaInstancePhysicsMaterialWriter;
class ColladaInstancePhysicsModelWriter;
class ColladaInstancePhysicsSceneWriter;
class ColladaInstanceRigidBodyWriter;
class ColladaInstanceRigidConstraintWriter;
class ColladaLibraryForceFieldsWriter;
class ColladaLibraryPhysicsMaterialsWriter;
class ColladaLibraryPhysicsModelsWriter;
class ColladaLibraryPhysicsScenesWriter;
class ColladaPhysicsMaterialWriter;
class ColladaPhysicsModelWriter;
class ColladaPhysicsSceneWriter;
class ColladaPlaneWriter;
class ColladaRefAttachmentWriter;
class ColladaRigidBodyWriter;
class ColladaRigidConstraintWriter;
class ColladaShapeWriter;
class ColladaSphereWriter;
class ColladaAlphaWriter;
class ColladaAnnotateWriter;
class ColladaArrayWriter;
class ColladaBinaryWriter;
class ColladaBindMaterialWriter;
class ColladaBindUniformWriter;
class ColladaBlinnWriter;
class ColladaColorTargetWriter;
class ColladaCompilerWriter;
class ColladaConstantFXWriter;
class ColladaCreate2DWriter;
class ColladaCreate3DWriter;
class ColladaCreateCubeWriter;
class ColladaDepthTargetWriter;
class ColladaEffectWriter;
class ColladaEvaluateWriter;
class ColladaFormatWriter;
class ColladaFXCommonColorOrTextureWriter;
class ColladaFXCommonFloatOrParamWriter;
class ColladaFXSamplerCommonWriter;
class ColladaImageWriter;
class ColladaInitFromWriter;
class ColladaInstanceEffectWriter;
class ColladaInstanceImageWriter;
class ColladaInstanceMaterialGeometryWriter;
class ColladaInstanceMaterialRenderingWriter;
class ColladaLambertWriter;
class ColladaLibraryEffectsWriter;
class ColladaLibraryImagesWriter;
class ColladaLibraryMaterialsWriter;
class ColladaLinkerWriter;
class ColladaMaterialWriter;
class ColladaPassWriter;
class ColladaPhongWriter;
class ColladaProfileBRIDGEWriter;
class ColladaProfileCGWriter;
class ColladaProfileCOMMONWriter;
class ColladaProfileGLESWriter;
class ColladaProfileGLES2Writer;
class ColladaProfileGLSLWriter;
class ColladaProgramWriter;
class ColladaRenderWriter;
class ColladaRGBWriter;
class ColladaShaderWriter;
class ColladaSourcesWriter;
class ColladaStatesWriter;
class ColladaStencilTargetWriter;
class ColladaTechniqueFXWriter;
class ColladaTexCombinerWriter;
class ColladaTexEnvWriter;
class ColladaTexturePipelineWriter;
class ColladaBRepWriter;
class ColladaCircleWriter;
class ColladaConeWriter;
class ColladaCurveWriter;
class ColladaCurvesWriter;
class ColladaCylinderBRepWriter;
class ColladaEdgesWriter;
class ColladaEllipseWriter;
class ColladaFacesWriter;
class ColladaHyperbolaWriter;
class ColladaLineWriter;
class ColladaNurbsWriter;
class ColladaNurbsSurfaceWriter;
class ColladaParabolaWriter;
class ColladaPCurvesWriter;
class ColladaShellsWriter;
class ColladaSolidsWriter;
class ColladaSurfaceWriter;
class ColladaSurfacesWriter;
class ColladaSurfaceCurvesWriter;
class ColladaSweptSurfaceWriter;
class ColladaTorusWriter;
class ColladaWiresWriter;
class ColladaArticulatedSystemWriter;
class ColladaAttachmentEndWriter;
class ColladaAttachmentFullWriter;
class ColladaAttachmentStartWriter;
class ColladaAxisInfoWriter;
class ColladaBindJointAxisWriter;
class ColladaBindKinematicsModelWriter;
class ColladaEffectorInfoWriter;
class ColladaKinematicsFrameWriter;
class ColladaInstanceArticulatedSystemWriter;
class ColladaInstanceJointWriter;
class ColladaInstanceKinematicsModelWriter;
class ColladaInstanceKinematicsSceneWriter;
class ColladaJointWriter;
class ColladaKinematicsWriter;
class ColladaKinematicsModelWriter;
class ColladaKinematicsSceneWriter;
class ColladaLibraryArticulatedSystemsWriter;
class ColladaLibraryJointsWriter;
class ColladaLibraryKinematicsModelsWriter;
class ColladaLibraryKinematicsScenesWriter;
class ColladaLinkWriter;
class ColladaMotionWriter;
class ColladaPrismaticWriter;
class ColladaRevoluteWriter;
class ColladaCOLLADAWriter;
class ColladaFileWriter;

// -------------------------------------------------------------------------------------------------------------------------------------
//		Enumerations
// -------------------------------------------------------------------------------------------------------------------------------------

// Represents a COLLADA file version.
BEGIN_ENUM(ColladaVersion)
	// Represents an unknown version.
	Unknown,
	// Represents COLLADA version 1.5.0.
	Version150,
END_ENUM()

// Represents an altitude mode.
BEGIN_ENUM(ColladaAltitudeMode)
	Absolute,
	RelativeToGround,
END_ENUM()

// Represents an axis.
BEGIN_ENUM(ColladaAxis)
	X,
	Y,
	Z,
END_ENUM()

// Represents a morph method.
BEGIN_ENUM(ColladaMorphMethod)
	Normalized,
	Relative,
END_ENUM()

// Represents a type of node.
BEGIN_ENUM(ColladaNodeType)
	Node,
	Joint,
END_ENUM()

// Represents a sampler boundary behavior.
BEGIN_ENUM(ColladaSamplerBehavior)
	Undefined,
	Constant,
	Gradient,
	Cycle,
	Oscillate,
	CycleRelative,
END_ENUM()

// Represents a GLES texture combiner operator.
BEGIN_ENUM(ColladaTexCombinerOperator)
	Replace,
	Modulate,
	Decal,
	Blend,
	Add,
	AddSigned,
	Interpolate,
	Subtract,
	Dot3Rgb,
	Dot3Rgba,
END_ENUM()

// Represents a GLES texture combiner source.
BEGIN_ENUM(ColladaTexCombinerSource)
	Undefined,
	Texture,
	Constant,
	Primary,
	Previous,
END_ENUM()

// Represents a GLES texture combiner operand.
BEGIN_ENUM(ColladaTexCombinerOperand)
	Undefined,
	SrcColor,
	OneMinusSrcColor,
	SrcAlpha,
	OneMinusSrcAlpha,
END_ENUM()

// Represents a cube texture face.
BEGIN_ENUM(ColladaCubeFace)
	PositiveX,
	NegativeX,
	PositiveY,
	NegativeY,
	PositiveZ,
	NegativeZ,
END_ENUM()

// Represents a draw operation parameter.
BEGIN_ENUM(ColladaDrawParameter)
	Geometry,
	SceneGeometry,
	SceneImage,
	FullScreenQuad,
	FullScreenQuadPlusHalfPixel,
END_ENUM()

// Represents the set of channels of a pixel format.
BEGIN_ENUM(ColladaFormatChannels)
	RGB,
	RGBA,
	RGBE,
	Luminance,
	LuminanceAlpha,
	Depth,
END_ENUM()

// Represents the range of a pixel format.
BEGIN_ENUM(ColladaFormatRange)
	SNorm,
	UNorm,
	SInt,
	UInt,
	Float,
END_ENUM()

// Represents the precision of a pixel format.
BEGIN_ENUM(ColladaFormatPrecision)
	Undefined,
	Default,
	Low,
	Mid,
	High,
	Max,
END_ENUM()

// Represents an opacity mode.
BEGIN_ENUM(ColladaOpaqueMode)
	AlphaOne,
	ColorZero,
	AlphaZero,
	ColorOne,
END_ENUM()

// Represents a wrap mode.
BEGIN_ENUM(ColladaTextureWrapMode)
	Wrap,
	Mirror,
	Clamp,
	Border,
	MirrorOnce,
END_ENUM()

// Represents a texture filter.
BEGIN_ENUM(ColladaTextureFilter)
	None,
	Nearest,
	Linear,
	Anisotropic,
END_ENUM()

// Represents a shader stage.
BEGIN_ENUM(ColladaShaderStage)
	Tesselation,
	Vertex,
	Geometry,
	Fragment,
END_ENUM()

// -------------------------------------------------------------------------------------------------------------------------------------
//		Base Classes & Macros
// -------------------------------------------------------------------------------------------------------------------------------------

// Represents the base class writing COLLADA elements.
class ColladaElementWriter
{
public:
	// Closes the element.
	void Close() { GetXmlWriter().CloseElement(); }

protected:
	ColladaElementWriter(ColladaFileWriter& writer) : m_Writer(writer) { }
	inline ColladaFileWriter& GetFileWriter() const;
	inline ColladaVersion::Type GetVersion() const;
	inline XmlFileWriter& GetXmlWriter() const;
private:
	ColladaFileWriter&		m_Writer;
};

#define COLLADA_ELEMENT_CLASS(className) class className sealed : public ColladaElementWriter

#define COLLADA_ELEMENT_CTOR(className) className(ColladaFileWriter& writer)
#define COLLADA_ELEMENT_CTOR(className, ...) className(ColladaFileWriter& writer, __VA_ARGS__)

#define COLLADA_ELEMENT_CTOR_IMPL(className) className(ColladaFileWriter& writer) : ColladaElementWriter(writer)
#define COLLADA_ELEMENT_CTOR_IMPL(className, ...) className(ColladaFileWriter& writer, __VA_ARGS__) : ColladaElementWriter(writer)

// -------------------------------------------------------------------------------------------------------------------------------------
//		Extensions
// -------------------------------------------------------------------------------------------------------------------------------------

// Adds the SetID() method to the class.
#define COLLADA_DECLARE_SetID \
	void SetID(const string& value)
#define COLLADA_DEFINE_SetID(className) \
	void className::SetID(const string& value) { GetXmlWriter().AddAttribute(ColladaStrings::ATTR_ID, value); }

// Adds the SetSID() method to the class.
#define COLLADA_DECLARE_SetSID \
	void SetSID(const string& value)
#define COLLADA_DEFINE_SetSID(className) \
	void className::SetSID(const string& value) { GetXmlWriter().AddAttribute(ColladaStrings::ATTR_SID, value); }

// Adds the SetName() method to the class.
#define COLLADA_DECLARE_SetName \
	void SetName(const string& value)
#define COLLADA_DEFINE_SetName(className) \
	void className::SetName(const string& value) { GetXmlWriter().AddAttribute(ColladaStrings::ATTR_NAME, value); }

// Adds the AddParam() method to the class.
#define COLLADA_DECLARE_AddParam \
	void AddParam(const string& type, const string& name = EmptyString, const string& semantic = EmptyString, const string& sid = EmptyString)
#define COLLADA_DEFINE_AddParam(className) \
	void className::AddParam(const string& type, const string& name, const string& semantic, const string& sid) \
	{ \
		GetXmlWriter().OpenElement(ColladaStrings::ELEM_PARAM); \
		GetXmlWriter().AddAttribute(ColladaStrings::ATTR_TYPE, type); \
		if (!name.empty()) GetXmlWriter().AddAttribute(ColladaStrings::ATTR_NAME, name); \
		if (!semantic.empty()) GetXmlWriter().AddAttribute(ColladaStrings::ATTR_SEMANTIC, name); \
		if (!sid.empty()) GetXmlWriter().AddAttribute(ColladaStrings::ATTR_SID, sid); \
		GetXmlWriter().CloseElement(); \
	}

// Adds the AddColor() method to the class.
#define COLLADA_DECLARE_AddColor \
	void AddColor(double r, double g, double b, const string& sid = EmptyString)
#define COLLADA_DEFINE_AddColor(className) \
	void className::AddColor(double r, double g, double b, const string& sid) \
	{ \
		GetXmlWriter().OpenElement(ColladaStrings::ELEM_COLOR); \
		if (!sid.empty()) GetXmlWriter().AddAttribute(ColladaStrings::ATTR_SID, sid); \
		GetXmlWriter().AddContent(r); \
		GetXmlWriter().AddContent(g); \
		GetXmlWriter().AddContent(b); \
		GetXmlWriter().CloseElement(); \
	}

// Adds the AddInput() method to the class.
#define COLLADA_DECLARE_AddInputShared \
	void AddInput(unsigned int offset, const string& semantic, const string& source, unsigned int set = -1)
#define COLLADA_DEFINE_AddInputShared(className) \
	void className::AddInput(unsigned int offset, const string& semantic, const string& source, unsigned int set) \
	{ \
		GetXmlWriter().OpenElement(ColladaStrings::ELEM_INPUT); \
		GetXmlWriter().AddAttribute(ColladaStrings::ATTR_OFFSET, offset); \
		GetXmlWriter().AddAttribute(ColladaStrings::ATTR_SEMANTIC, semantic); \
		GetXmlWriter().AddAttribute(ColladaStrings::ATTR_SOURCE, source); \
		if (set >= 0) GetXmlWriter().AddAttribute(ColladaStrings::ATTR_SET, set); \
		GetXmlWriter().CloseElement(); \
	}

// Adds the AddInput() method to the class.
#define COLLADA_DECLARE_AddInputUnshared \
	void AddInput(const string& semantic, const string& source)
#define COLLADA_DEFINE_AddInputUnshared(className) \
	void className::AddInput(const string& semantic, const string& source) \
	{ \
		GetXmlWriter().OpenElement(ColladaStrings::ELEM_INPUT); \
		GetXmlWriter().AddAttribute(ColladaStrings::ATTR_SEMANTIC, semantic); \
		GetXmlWriter().AddAttribute(ColladaStrings::ATTR_SOURCE, source); \
		GetXmlWriter().CloseElement(); \
	}

// Adds the AddSetParam() method to the class.
#define COLLADA_DECLARE_AddSetParam \
	void AddSetParam(const string& ref, int value); \
	void AddSetParam(const string& ref, bool value); \
	void AddSetParam(const string& ref, double value); \
	void AddSetParam(const string& ref, const string& sidref); \
	void AddSetParamConnectParam(const string& ref, const string& connectToRef)
#define COLLADA_DEFINE_AddSetParam(className) \
	void className::AddSetParam(const string& ref, int value) \
	{ \
		GetXmlWriter().OpenElement(ColladaStrings::ELEM_SETPARAM); \
		GetXmlWriter().AddAttribute(ColladaStrings::ATTR_REF, ref); \
		GetXmlWriter().OpenElement(ColladaStrings::ELEM_INT); \
		GetXmlWriter().AddContent(value); \
		GetXmlWriter().CloseElement(); \
		GetXmlWriter().CloseElement(); \
	} \
	void className::AddSetParam(const string& ref, bool value) \
	{ \
		GetXmlWriter().OpenElement(ColladaStrings::ELEM_SETPARAM); \
		GetXmlWriter().AddAttribute(ColladaStrings::ATTR_REF, ref); \
		GetXmlWriter().OpenElement(ColladaStrings::ELEM_BOOL); \
		GetXmlWriter().AddContent(value); \
		GetXmlWriter().CloseElement(); \
		GetXmlWriter().CloseElement(); \
	} \
	void className::AddSetParam(const string& ref, double value) \
	{ \
		GetXmlWriter().OpenElement(ColladaStrings::ELEM_SETPARAM); \
		GetXmlWriter().AddAttribute(ColladaStrings::ATTR_REF, ref); \
		GetXmlWriter().OpenElement(ColladaStrings::ELEM_FLOAT); \
		GetXmlWriter().AddContent(value); \
		GetXmlWriter().CloseElement(); \
		GetXmlWriter().CloseElement(); \
	} \
	void className::AddSetParam(const string& ref, const string& sidref) \
	{ \
		GetXmlWriter().OpenElement(ColladaStrings::ELEM_SETPARAM); \
		GetXmlWriter().AddAttribute(ColladaStrings::ATTR_REF, ref); \
		GetXmlWriter().OpenElement(ColladaStrings::ELEM_SIDREF); \
		GetXmlWriter().AddContent(sidref); \
		GetXmlWriter().CloseElement(); \
		GetXmlWriter().CloseElement(); \
	} \
	void className::AddSetParamConnectParam(const string& ref, const string& connectToRef) \
	{ \
		GetXmlWriter().OpenElement(ColladaStrings::ELEM_SETPARAM); \
		GetXmlWriter().AddAttribute(ColladaStrings::ATTR_REF, ref); \
		GetXmlWriter().OpenElement(ColladaStrings::ELEM_CONNECT_PARAM); \
		GetXmlWriter().AddAttribute(ColladaStrings::ATTR_REF, connectToRef); \
		GetXmlWriter().CloseElement(); \
		GetXmlWriter().CloseElement(); \
	}

// Adds the AddRotate() method to the class.
#define COLLADA_DECLARE_AddRotate \
	void AddRotate(double axisX, double axisY, double axisZ, double angle, const string& sid = EmptyString)
#define COLLADA_DEFINE_AddRotate(className) \
	void className::AddRotate(double axisX, double axisY, double axisZ, double angle, const string& sid) \
	{ \
		GetXmlWriter().OpenElement(ColladaStrings::ELEM_ROTATE); \
		if (!sid.empty()) GetXmlWriter().AddAttribute(ColladaStrings::ATTR_SID, sid); \
		GetXmlWriter().AddContent(axisX); \
		GetXmlWriter().AddContent(axisY); \
		GetXmlWriter().AddContent(axisZ); \
		GetXmlWriter().AddContent(angle); \
		GetXmlWriter().CloseElement(); \
	}

// Adds the AddTranslate() method to the class.
#define COLLADA_DECLARE_AddTranslate \
	void AddTranslate(double x, double y, double z, const string& sid = EmptyString)
#define COLLADA_DEFINE_AddTranslate(className) \
	void className::AddTranslate(double x, double y, double z, const string& sid) \
	{ \
		GetXmlWriter().OpenElement(ColladaStrings::ELEM_TRANSLATE); \
		if (!sid.empty()) GetXmlWriter().AddAttribute(ColladaStrings::ATTR_SID, sid); \
		GetXmlWriter().AddContent(x); \
		GetXmlWriter().AddContent(y); \
		GetXmlWriter().AddContent(z); \
		GetXmlWriter().CloseElement(); \
	}

// Adds the AddConstantAttenuation(), AddLinearAttenuation() and AddQuadraticAttenuation() methods to the class.
#define COLLADA_DECLARE_AddConstantLinearQuadraticAttenuation \
	void AddConstantAttenuation(double value, const string& sid = EmptyString); \
	void AddLinearAttenuation(double value, const string& sid = EmptyString); \
	void AddQuadraticAttenuation(double value, const string& sid = EmptyString)
#define COLLADA_DEFINE_AddConstantLinearQuadraticAttenuation(className) \
	void className::AddConstantAttenuation(double value, const string& sid) \
	{ \
		GetXmlWriter().OpenElement(ColladaStrings::ELEM_CONSTANT_ATTENUATION); \
		if (!sid.empty()) GetXmlWriter().AddAttribute(ColladaStrings::ATTR_SID, sid); \
		GetXmlWriter().AddContent(value); \
		GetXmlWriter().CloseElement(); \
	} \
	void className::AddLinearAttenuation(double value, const string& sid) \
	{ \
		GetXmlWriter().OpenElement(ColladaStrings::ELEM_LINEAR_ATTENUATION); \
		if (!sid.empty()) GetXmlWriter().AddAttribute(ColladaStrings::ATTR_SID, sid); \
		GetXmlWriter().AddContent(value); \
		GetXmlWriter().CloseElement(); \
	} \
	void className::AddQuadraticAttenuation(double value, const string& sid) \
	{ \
		GetXmlWriter().OpenElement(ColladaStrings::ELEM_QUADRATIC_ATTENUATION); \
		if (!sid.empty()) GetXmlWriter().AddAttribute(ColladaStrings::ATTR_SID, sid); \
		GetXmlWriter().AddContent(value); \
		GetXmlWriter().CloseElement(); \
	}

// Adds the AddBind() method to the class.
#define COLLADA_DECLARE_AddBindKinematics \
	void AddBind(const string& symbol, int value); \
	void AddBind(const string& symbol, bool value); \
	void AddBind(const string& symbol, float value); \
	void AddBind(const string& symbol, const string& sidref); \
	void AddBindParam(const string& symbol, const string& ref)
#define COLLADA_DEFINE_AddBindKinematics(className) \
	void className::AddBind(const string& symbol, int value) \
	{ \
		GetXmlWriter().OpenElement(ColladaStrings::ELEM_BIND); \
		GetXmlWriter().AddAttribute(ColladaStrings::ATTR_SYMBOL, symbol); \
		GetXmlWriter().OpenElement(ColladaStrings::ELEM_INT); \
		GetXmlWriter().AddContent(value); \
		GetXmlWriter().CloseElement(); \
		GetXmlWriter().CloseElement(); \
	} \
	void className::AddBind(const string& symbol, bool value) \
	{ \
		GetXmlWriter().OpenElement(ColladaStrings::ELEM_BIND); \
		GetXmlWriter().AddAttribute(ColladaStrings::ATTR_SYMBOL, symbol); \
		GetXmlWriter().OpenElement(ColladaStrings::ELEM_BOOL); \
		GetXmlWriter().AddContent(value); \
		GetXmlWriter().CloseElement(); \
		GetXmlWriter().CloseElement(); \
	} \
	void className::AddBind(const string& symbol, float value) \
	{ \
		GetXmlWriter().OpenElement(ColladaStrings::ELEM_BIND); \
		GetXmlWriter().AddAttribute(ColladaStrings::ATTR_SYMBOL, symbol); \
		GetXmlWriter().OpenElement(ColladaStrings::ELEM_FLOAT); \
		GetXmlWriter().AddContent(value); \
		GetXmlWriter().CloseElement(); \
		GetXmlWriter().CloseElement(); \
	} \
	void className::AddBind(const string& symbol, const string& sidref) \
	{ \
		GetXmlWriter().OpenElement(ColladaStrings::ELEM_BIND); \
		GetXmlWriter().AddAttribute(ColladaStrings::ATTR_SYMBOL, symbol); \
		GetXmlWriter().OpenElement(ColladaStrings::ELEM_SIDREF); \
		GetXmlWriter().AddContent(sidref); \
		GetXmlWriter().CloseElement(); \
		GetXmlWriter().CloseElement(); \
	} \
	void className::AddBindParam(const string& symbol, const string& ref) \
	{ \
		GetXmlWriter().OpenElement(ColladaStrings::ELEM_BIND); \
		GetXmlWriter().AddAttribute(ColladaStrings::ATTR_SYMBOL, symbol); \
		GetXmlWriter().OpenElement(ColladaStrings::ELEM_PARAM); \
		GetXmlWriter().AddAttribute(ColladaStrings::ATTR_REF, ref); \
		GetXmlWriter().CloseElement(); \
		GetXmlWriter().CloseElement(); \
	}

// Adds the OpenAsset() method to the class.
#define COLLADA_DECLARE_OpenAsset \
	ColladaAssetWriter OpenAsset()
#define COLLADA_DEFINE_OpenAsset(className) \
	ColladaAssetWriter className::OpenAsset() { return ColladaAssetWriter(GetFileWriter()); }

// Adds the OpenExtra() method to the class.
#define COLLADA_DECLARE_OpenExtra \
	ColladaExtraWriter OpenExtra()
#define COLLADA_DEFINE_OpenExtra(className) \
	ColladaExtraWriter className::OpenExtra() { return ColladaExtraWriter(GetFileWriter()); }

// Adds the OpenTechnique() method to the class.
#define COLLADA_DECLARE_OpenTechniqueCore \
	ColladaTechniqueCoreWriter OpenTechnique(const string& profile)
#define COLLADA_DEFINE_OpenTechniqueCore(className) \
	ColladaTechniqueCoreWriter className::OpenTechnique(const string& profile) { return ColladaTechniqueCoreWriter(GetFileWriter(), profile); }

// Adds methods for adding and filling a <p> element to the class.
#define COLLADA_DECLARE_Indices \
	void BeginIndices(); \
	void AppendIndex(int value); \
	void AppendIndices(int* values, int count); \
	void EndEndices()
#define COLLADA_DEFINE_Indices(className) \
	void className::BeginIndices() { GetXmlWriter().OpenElement(ColladaStrings::ELEM_P); } \
	void className::AppendIndex(int value) { GetXmlWriter().AddContent(value); } \
	void className::AppendIndices(int* values, int count) { GetXmlWriter().AddContent(values, count); } \
	void className::EndEndices() { GetXmlWriter().CloseElement(); }

// Adds methods for adding and filling a <vcount> element to the class.
#define COLLADA_DECLARE_VCount \
	void BeginVCount(); \
	void AppendCount(int value); \
	void AppendCounts(int* values, int count); \
	void EndVCount()
#define COLLADA_DEFINE_VCount(className) \
	void className::BeginVCount() { GetXmlWriter().OpenElement(ColladaStrings::ELEM_VCOUNT); } \
	void className::AppendCount(int value) { GetXmlWriter().AddContent(value); } \
	void className::AppendCounts(int* values, int count) { GetXmlWriter().AddContent(values, count); } \
	void className::EndVCount() { GetXmlWriter().CloseElement(); }

// -------------------------------------------------------------------------------------------------------------------------------------
//		<accessor>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <accessor> element.
COLLADA_ELEMENT_CLASS(ColladaAccessorWriter)
{
public:
	// Sets the optional 'offset' attribute value.
	void SetOffset(unsigned int value);
	// Sets the optional 'stride' attribute value.
	void SetStride(unsigned int value);

	// Adds a <param> element.
	COLLADA_DECLARE_AddParam;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaAccessorWriter, const string& source, unsigned int count);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<ambient> (Core)
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <ambient> element.
COLLADA_ELEMENT_CLASS(ColladaAmbientCoreWriter)
{
public:
	// Adds a <color> element.
	COLLADA_DECLARE_AddColor;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaAmbientCoreWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<animation>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <animation> element.
COLLADA_ELEMENT_CLASS(ColladaAnimationWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Adds a <channel> element.
	void AddChannel(const string& source, const string& target);

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens an <animation> element.
	ColladaAnimationWriter OpenAnimation();
	// Opens a <source> element.
	ColladaSourceCoreWriter OpenSource(const string& id);
	// Opens a <sampler> element.
	ColladaSamplerWriter OpenSampler();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaAnimationWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<animation_clip>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <animation_clip> element.
COLLADA_ELEMENT_CLASS(ColladaAnimationClipWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;
	// Sets the optional 'start' attribute value.
	void SetStart(double value);
	// Sets the optional 'end' attribute value.
	void SetEnd(double value);

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens an <instance_animation> element.
	ColladaInstanceAnimationWriter OpenInstanceAnimation(const string& url);
	// Opens an <instance_formula> element.
	ColladaInstanceFormulaWriter OpenInstanceFormula(const string& url);
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaAnimationClipWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<asset>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <asset> element.
COLLADA_ELEMENT_CLASS(ColladaAssetWriter)
{
public:
	// Adds a <coverage> element.
	void AddCoverage(double longitude, double latitude, double altitude, ColladaAltitudeMode::Type altitudeMode);
	// Adds a <created> element.
	void AddCreated(time_t value);
	// Adds a <keywords> element.
	void AddKeywords(const string& value);
	// Adds a <modified> element.
	void AddModified(time_t value);
	// Adds a <revision> element.
	void AddRevision(const string& value);
	// Adds a <subject> element.
	void AddSubject(const string& value);
	// Adds a <title> element.
	void AddTitle(const string& value);
	// Adds a <unit> element.
	void AddUnit(const string& name = "meter", double meter = 1.0);
	// Adds an <up_axis> element.
	void AddUpAxis(ColladaAxis::Type value);

	// Opens a <constributor> element.
	ColladaContributorWriter OpenContributor();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaAssetWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<bool_array>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <bool_array> element.
COLLADA_ELEMENT_CLASS(ColladaBoolArrayWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Appends a value at the end of the array.
	void Append(bool value);
	// Appends a list of values at the end of the array.
	void Append(bool* values, int count);

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaBoolArrayWriter, unsigned int count);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<camera>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <camera> element.
COLLADA_ELEMENT_CLASS(ColladaCameraWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens an <optics> element.
	ColladaOpticsWriter OpenOptics();
	// Opens an <imager> element.
	ColladaImagerWriter OpenImager();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaCameraWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<contributor>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <contributor> element.
COLLADA_ELEMENT_CLASS(ColladaContributorWriter)
{
public:
	// Adds an <author> element.
	void AddAuthor(const string& value);
	// Adds an <author_email> element.
	void AddAuthorEmail(const string& value);
	// Adds an <author_website> element.
	void AddAuthorWebsite(const string& value);
	// Adds an <authoring_tool> element.
	void AddAuthoringTool(const string& value);
	// Adds a <comments> element.
	void AddComments(const string& value);
	// Adds a <copyright> element.
	void AddCopyright(const string& value);
	// Adds a <source_data> element.
	void AddSourceData(const string& value);

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaContributorWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<controller>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <controller> element.
COLLADA_ELEMENT_CLASS(ColladaControllerWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <skin> element.
	ColladaSkinWriter OpenSkin(const string& source);
	// Opens a <morph> element.
	ColladaMorphWriter OpenMorph(const string& source);
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaControllerWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<control_vertices>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <control_vertices> element.
COLLADA_ELEMENT_CLASS(ColladaControlVerticesWriter)
{
public:
	// Adds an <input> element.
	COLLADA_DECLARE_AddInputUnshared;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaControlVerticesWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<directional>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <directional> element.
COLLADA_ELEMENT_CLASS(ColladaDirectionalWriter)
{
public:
	// Adds a <color> element.
	COLLADA_DECLARE_AddColor;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaDirectionalWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<evaluate_scene>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <evaluate_scene> element.
COLLADA_ELEMENT_CLASS(ColladaEvaluateSceneWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;
	// Sets the optional 'sid' attribute value.
	COLLADA_DECLARE_SetSID;
	// Sets the optional 'enable' attribute value.
	void SetEnable(bool value);

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <render> element.
	ColladaRenderWriter OpenRender();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaEvaluateSceneWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<extra>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <extra> element.
COLLADA_ELEMENT_CLASS(ColladaExtraWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;
	// Sets the optional 'type' attribute value.
	void SetType(const string& value);

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <technique> element.
	COLLADA_DECLARE_OpenTechniqueCore;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaExtraWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<float_array>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <float_array> element.
COLLADA_ELEMENT_CLASS(ColladaFloatArrayWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;
	// Sets the optional 'digits' attribute value.
	void SetDigits(unsigned char value);
	// Sets the optional 'magnitude' attribute value.
	void SetMagnitude(short value);

	// Appends a value at the end of the array.
	void Append(double value);
	// Appends a list of values at the end of the array.
	void Append(float* values, int count);
	void Append(double* values, int count);

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaFloatArrayWriter, unsigned int count);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<formula>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <formula> element.
COLLADA_ELEMENT_CLASS(ColladaFormulaWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;
	// Sets the optional 'sid' attribute value.
	COLLADA_DECLARE_SetSID;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// TODO: <formula>

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaFormulaWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<geometry>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <geometry> element.
COLLADA_ELEMENT_CLASS(ColladaGeometryWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <convex_mesh> element.
	ColladaConvexMeshWriter OpenConvexMesh();
	// Opens a <mesh> element.
	ColladaMeshWriter OpenMesh();
	// Opens a <spline> element.
	ColladaSplineWriter OpenSpline();
	// Opens a <brep> element.
	ColladaBRepWriter OpenBRep();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaGeometryWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<IDREF_array>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <IDREF_array> element.
COLLADA_ELEMENT_CLASS(ColladaIDREFArrayWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Appends a value at the end of the array.
	void Append(const string& value);

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaIDREFArrayWriter, unsigned int count);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<imager>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <imager> element.
COLLADA_ELEMENT_CLASS(ColladaImagerWriter)
{
public:
	// Opens a <technique> element.
	COLLADA_DECLARE_OpenTechniqueCore;
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaImagerWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<instance_animation>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <instance_animation> element.
COLLADA_ELEMENT_CLASS(ColladaInstanceAnimationWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaInstanceAnimationWriter, const string& url);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<instance_camera>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <instance_camera> element.
COLLADA_ELEMENT_CLASS(ColladaInstanceCameraWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaInstanceCameraWriter, const string& url);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<instance_controller>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <instance_controller> element.
COLLADA_ELEMENT_CLASS(ColladaInstanceControllerWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens a <skeleton> element.
	ColladaSkeletonWriter OpenSkeleton();
	// Opens a <bind_material> element.
	ColladaBindMaterialWriter OpenBindMaterial();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaInstanceControllerWriter, const string& url);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<instance_formula>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <instance_formula> element.
COLLADA_ELEMENT_CLASS(ColladaInstanceFormulaWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Adds a <setparam> element.
	COLLADA_DECLARE_AddSetParam;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaInstanceFormulaWriter, const string& url);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<instance_geometry>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <instance_animation> element.
COLLADA_ELEMENT_CLASS(ColladaInstanceGeometryWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens a <bind_material> element.
	ColladaBindMaterialWriter OpenBindMaterial();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaInstanceGeometryWriter, const string& url);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<instance_light>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <instance_light> element.
COLLADA_ELEMENT_CLASS(ColladaInstanceLightWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaInstanceLightWriter, const string& url);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<instance_node>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <instance_node> element.
COLLADA_ELEMENT_CLASS(ColladaInstanceNodeWriter)
{
public:
	// Sets the optional 'sid' attribute value.
	COLLADA_DECLARE_SetSID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Sets the optional 'proxy' attribute value.
	void SetProxy(const string& value);

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaInstanceNodeWriter, const string& url);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<instance_visual_scene>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <instance_visual_scene> element.
COLLADA_ELEMENT_CLASS(ColladaInstanceVisualSceneWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaInstanceVisualSceneWriter, const string& url);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<int_array>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <int_array> element.
COLLADA_ELEMENT_CLASS(ColladaIntArrayWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;
	// Sets the optional 'minInclusive' attribute value.
	void SetMinInclusive(int value);
	// Sets the optional 'maxInclusive' attribute value.
	void SetMaxInclusive(int value);

	// Appends a value at the end of the array.
	void Append(int value);
	// Appends a list of values at the end of the array.
	void Append(int* values, int count);

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaIntArrayWriter, unsigned int count);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<joints>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <joints> element.
COLLADA_ELEMENT_CLASS(ColladaJointsWriter)
{
public:
	// Adds an <input> element.
	COLLADA_DECLARE_AddInputUnshared;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaJointsWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<library_animation_clips>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <library_animation_clips> element.
COLLADA_ELEMENT_CLASS(ColladaLibraryAnimationClipsWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens an <animation_clip> element.
	ColladaAnimationClipWriter OpenAnimationClip();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaLibraryAnimationClipsWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<library_animations>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <library_animations> element.
COLLADA_ELEMENT_CLASS(ColladaLibraryAnimationsWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens an <animation> element.
	ColladaAnimationWriter OpenAnimation();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaLibraryAnimationsWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<library_cameras>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <library_cameras> element.
COLLADA_ELEMENT_CLASS(ColladaLibraryCamerasWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <camera> element.
	ColladaCameraWriter OpenCamera();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaLibraryCamerasWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<library_controllers>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <library_controllers> element.
COLLADA_ELEMENT_CLASS(ColladaLibraryControllersWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <controller> element.
	ColladaControllerWriter OpenController();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaLibraryControllersWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<library_formulas>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <library_formulas> element.
COLLADA_ELEMENT_CLASS(ColladaLibraryFormulasWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <formula> element.
	ColladaFormulaWriter OpenFormula();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaLibraryFormulasWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<library_geometries>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <library_geometries> element.
COLLADA_ELEMENT_CLASS(ColladaLibraryGeometriesWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <geometry> element.
	ColladaGeometryWriter OpenGeometry();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaLibraryGeometriesWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<library_lights>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <library_lights> element.
COLLADA_ELEMENT_CLASS(ColladaLibraryLightsWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <light> element.
	ColladaLightWriter OpenLight();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaLibraryLightsWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<library_nodes>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <library_nodes> element.
COLLADA_ELEMENT_CLASS(ColladaLibraryNodesWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <node> element.
	ColladaNodeWriter OpenNode();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaLibraryNodesWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<library_visual_scenes>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <library_visual_scenes> element.
COLLADA_ELEMENT_CLASS(ColladaLibraryVisualScenesWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <visual_scene> element.
	ColladaVisualSceneWriter OpenVisualScene();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaLibraryVisualScenesWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<light>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <light> element.
COLLADA_ELEMENT_CLASS(ColladaLightWriter)
{
public:
	// Writes a <technique_common> element.
	COLLADA_ELEMENT_CLASS(TechniqueCommonWriter)
	{
	public:
		// Opens an <ambient> element.
		ColladaAmbientCoreWriter OpenAmbient();
		// Opens a <directional> element.
		ColladaDirectionalWriter OpenDirectional();
		// Opens a <point> element.
		ColladaPointWriter OpenPoint();
		// Opens a <spot> element.
		ColladaSpotWriter OpenSpot();

		// Constructor.
		COLLADA_ELEMENT_CTOR(TechniqueCommonWriter);
	};

	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <technique_common> element.
	TechniqueCommonWriter OpenTechniqueCommon();
	// Opens a <technique> element.
	COLLADA_DECLARE_OpenTechniqueCore;
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaLightWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<lines>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <lines> element.
COLLADA_ELEMENT_CLASS(ColladaLinesWriter)
{
public:
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;
	// Sets the optional 'material' attribute value.
	void SetMaterial(const string& value);

	// Adds an <input> element.
	COLLADA_DECLARE_AddInputShared;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Adds a <p> element.
	COLLADA_DECLARE_Indices;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaLinesWriter, unsigned int count);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<linestrips>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <linestrips> element.
COLLADA_ELEMENT_CLASS(ColladaLineStripsWriter)
{
public:
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;
	// Sets the optional 'material' attribute value.
	void SetMaterial(const string& value);

	// Adds an <input> element.
	COLLADA_DECLARE_AddInputShared;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Adds a <p> element.
	COLLADA_DECLARE_Indices;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaLineStripsWriter, unsigned int count);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<mesh>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <mesh> element.
COLLADA_ELEMENT_CLASS(ColladaMeshWriter)
{
public:
	// Opens a <source> element.
	ColladaSourceCoreWriter OpenSource(const string& id);
	// Opens a <vertices> element.
	ColladaVerticesWriter OpenVertices(const string& id);
	// Opens a <lines> element.
	ColladaLinesWriter OpenLines(unsigned int count);
	// Opens a <linestrips> element.
	ColladaLineStripsWriter OpenLineStrips(unsigned int count);
	// Opens a <polygons> element.
	ColladaPolygonsWriter OpenPolygons(unsigned int count);
	// Opens a <polylist> element.
	ColladaPolyListWriter OpenPolyList(unsigned int count);
	// Opens a <triangles> element.
	ColladaTrianglesWriter OpenTriangles(unsigned int count);
	// Opens a <trifans> element.
	ColladaTriFansWriter OpenTriFans(unsigned int count);
	// Opens a <tristrips> element.
	ColladaTriStripsWriter OpenTriStrips(unsigned int count);
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaMeshWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<morph>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <morph> element.
COLLADA_ELEMENT_CLASS(ColladaMorphWriter)
{
public:
	// Sets the optional 'method' attribute value.
	void SetMethod(ColladaMorphMethod::Type value);

	// Opens a <source> element.
	ColladaSourceCoreWriter OpenSource(const string& id);
	// Opens a <targets> element.
	ColladaTargetsWriter OpenTargets();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaMorphWriter, const string& source);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<Name_array>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <Name_array> element.
COLLADA_ELEMENT_CLASS(ColladaNameArrayWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Appends a value at the end of the array.
	void Append(const string& value);

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaNameArrayWriter, unsigned int count);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<newparam>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <newparam> element.
COLLADA_ELEMENT_CLASS(ColladaNewParamWriter)
{
public:
	// Adds an <int> element.
	void AddValue(int value);
	// Adds a <bool> element.
	void AddValue(bool value);
	// Adds a <float> element.
	void AddValue(double value);
	// Adds a <SIDREF> element.
	void AddValue(const string& value);

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaNewParamWriter, const string& sid);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<newparam> (FX)
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <newparam> element.
COLLADA_ELEMENT_CLASS(ColladaNewParamFXWriter)
{
public:
	// TODO: <newparam> (FX)

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaNewParamFXWriter, const string& sid);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<node>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <node> element.
COLLADA_ELEMENT_CLASS(ColladaNodeWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;
	// Sets the optional 'sid' attribute value.
	COLLADA_DECLARE_SetSID;
	// Sets the optional 'type' attribute value.
	void SetType(ColladaNodeType::Type value);
	// Sets the optional 'layer' attribute value.
	void SetLayer(const string& value);

	// Adds a <lookat> element.
	void AddLookAt(double posX, double posY, double posZ, double targetX, double targetY, double targetZ, double upX, double upY, double upZ, const string& sid = EmptyString);
	// Adds a <matrix> element.
	void AddMatrix(double m11, double m12, double m13, double m14, double m21, double m22, double m23, double m24, double m31, double m32, double m33, double m34, double m41, double m42, double m43, double m44, const string& sid = EmptyString);
	// Adds a <scale> element.
	void AddScale(double x, double y, double z, const string& sid = EmptyString);
	// Adds a <skew> element.
	void AddSkew(double angle, double axis1X, double axis1Y, double axis1Z, double axis2X, double axis2Y, double axis2Z, const string& sid = EmptyString);
	// Adds a <rotate> element.
	COLLADA_DECLARE_AddRotate;
	// Adds a <translate> element.
	COLLADA_DECLARE_AddTranslate;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens an <instance_camera> element.
	ColladaInstanceCameraWriter OpenInstanceCamera(const string& url);
	// Opens an <instance_controller> element.
	ColladaInstanceControllerWriter OpenInstanceController(const string& url);
	// Opens an <instance_geometry> element.
	ColladaInstanceGeometryWriter OpenInstanceGeometry(const string& url);
	// Opens an <instance_light> element.
	ColladaInstanceLightWriter OpenInstanceLight(const string& url);
	// Opens an <instance_node> element.
	ColladaInstanceNodeWriter OpenInstanceNode(const string& url);
	// Opens a <node> element.
	ColladaNodeWriter OpenNode();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaNodeWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<optics>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <optics> element.
COLLADA_ELEMENT_CLASS(ColladaOpticsWriter)
{
public:
	// Writes a <technique_common> element.
	COLLADA_ELEMENT_CLASS(TechniqueCommonWriter)
	{
	public:
		// Opens an <orthographic> element.
		ColladaOrthographicWriter OpenOrthographic();
		// Opens a <perspective> element.
		ColladaPerspectiveWriter OpenPerspective();

		// Constructor.
		COLLADA_ELEMENT_CTOR(TechniqueCommonWriter);
	};

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <technique_common> element.
	TechniqueCommonWriter OpenTechniqueCommon();
	// Opens a <technique> element.
	COLLADA_DECLARE_OpenTechniqueCore;
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.	
	COLLADA_ELEMENT_CTOR(ColladaOpticsWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<orthographic>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <orthographic> element.
COLLADA_ELEMENT_CLASS(ColladaOrthographicWriter)
{
public:
	// Adds an <xmag> element.
	void AddXMag(double value, const string& sid = EmptyString);
	// Adds an <ymag> element.
	void AddYMag(double value, const string& sid = EmptyString);
	// Adds an <aspect_ratio> element.
	void AddAspectRatio(double value, const string& sid = EmptyString);
	// Adds a <znear> element.
	void AddZNear(double value, const string& sid = EmptyString);
	// Adds a <zfar> element.
	void AddZFar(double value, const string& sid = EmptyString);

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaOrthographicWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<perspective>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <perspective> element.
COLLADA_ELEMENT_CLASS(ColladaPerspectiveWriter)
{
public:
	// Adds an <xfov> element.
	void AddXFov(double value, const string& sid = EmptyString);
	// Adds an <yfov> element.
	void AddYFov(double value, const string& sid = EmptyString);
	// Adds an <aspect_ratio> element.
	void AddAspectRatio(double value, const string& sid = EmptyString);
	// Adds a <znear> element.
	void AddZNear(double value, const string& sid = EmptyString);
	// Adds a <zfar> element.
	void AddZFar(double value, const string& sid = EmptyString);

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaPerspectiveWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<point>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <point> element.
COLLADA_ELEMENT_CLASS(ColladaPointWriter)
{
public:
	// Adds a <color> element.
	COLLADA_DECLARE_AddColor;
	// Adds a <*_attenuation> element.
	COLLADA_DECLARE_AddConstantLinearQuadraticAttenuation;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaPointWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<polygons>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <polygons> element.
COLLADA_ELEMENT_CLASS(ColladaPolygonsWriter)
{
public:
	// Writes a <ph> element.
	COLLADA_ELEMENT_CLASS(PolygonHolesWriter)
	{
	public:
		// Adds a <p> element.
		COLLADA_DECLARE_Indices;
		// Opens a <h> element to start writing hole indices.
		void BeginHoleIndices();
		// Closes the <h> element.
		void EndHoleEndices();

		// Constructor.
		COLLADA_ELEMENT_CTOR(PolygonHolesWriter);
	};

	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;
	// Sets the optional 'material' attribute value.
	void SetMaterial(const string& value);

	// Adds an <input> element.
	COLLADA_DECLARE_AddInputShared;

	// Opens a <ph> element.
	PolygonHolesWriter OpenPolygonsWithHoles();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Adds a <p> element.
	COLLADA_DECLARE_Indices;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaPolygonsWriter, unsigned int count);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<polylist>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <polylist> element.
COLLADA_ELEMENT_CLASS(ColladaPolyListWriter)
{
public:
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;
	// Sets the optional 'material' attribute value.
	void SetMaterial(const string& value);

	// Adds an <input> element.
	COLLADA_DECLARE_AddInputShared;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;
	// Adds a <vcount> element.
	COLLADA_DECLARE_VCount;
	// Adds a <p> element.
	COLLADA_DECLARE_Indices;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaPolyListWriter, unsigned int count);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<sampler>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <sampler> element.
COLLADA_ELEMENT_CLASS(ColladaSamplerWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'pre_behavior' attribute value.
	void SetPreBehavior(ColladaSamplerBehavior::Type value);
	// Sets the optional 'post_behavior' attribute value.
	void SetPostBehavior(ColladaSamplerBehavior::Type value);

	// Adds an <input> element.
	COLLADA_DECLARE_AddInputUnshared;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaSamplerWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<scene>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <scene> element.
COLLADA_ELEMENT_CLASS(ColladaSceneWriter)
{
public:
	// Opens an <instance_physics_scene> element.
	ColladaInstancePhysicsSceneWriter OpenInstancePhysicsScene(const string& url);
	// Opens an <instance_visual_scene> element.
	ColladaInstanceVisualSceneWriter OpenInstanceVisualScene(const string& url);
	// Opens an <instance_kinematics_scene> element.
	ColladaInstanceKinematicsSceneWriter OpenInstanceKinematicsScene(const string& url);
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaSceneWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<setparam>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <setparam> element.
COLLADA_ELEMENT_CLASS(ColladaSetParamFXWriter)
{
public:
	// TODO: setparam (FX)

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaSetParamFXWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<SIDREF_array>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <SIDREF_array> element.
COLLADA_ELEMENT_CLASS(ColladaSIDREFArrayWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;
	
	// Appends a value at the end of the array.
	void Append(const string& value);

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaSIDREFArrayWriter, unsigned int count);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<skeleton>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <skeleton> element.
COLLADA_ELEMENT_CLASS(ColladaSkeletonWriter)
{
public:
	// Appends a value.
	void Append(const string& value);

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaSkeletonWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<skin>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <skin> element.
COLLADA_ELEMENT_CLASS(ColladaSkinWriter)
{
public:
	// Adds a <bind_shape_matrix> element.
	void AddBindShapeMatrix(double m11, double m12, double m13, double m14, double m21, double m22, double m23, double m24, double m31, double m32, double m33, double m34, double m41, double m42, double m43, double m44);

	// Opens a <source> element.
	ColladaSourceCoreWriter OpenSource(const string& id);
	// Opens a <joint> element.
	ColladaJointsWriter OpenJoints();
	// Opens a <vertex_weights> element.
	ColladaVertexWeightsWriter OpenVertexWeights(unsigned int count);
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaSkinWriter, const string& source);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<source> (Core)
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <source> element.
COLLADA_ELEMENT_CLASS(ColladaSourceCoreWriter)
{
public:
	// Writes a <technique_common> element.
	COLLADA_ELEMENT_CLASS(TechniqueCommonWriter)
	{
	public:
		// Opens an <asset> element.
		COLLADA_DECLARE_OpenAsset;

		// Constructor.
		COLLADA_ELEMENT_CTOR(TechniqueCommonWriter);
	};

	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <bool_array> element.
	ColladaBoolArrayWriter OpenBoolArray(unsigned int count);
	// Opens a <float_array> element.
	ColladaFloatArrayWriter OpenFloatArray(unsigned int count);
	// Opens a <IDREF_array> element.
	ColladaIDREFArrayWriter OpenIDREFArray(unsigned int count);
	// Opens a <int_array> element.
	ColladaIntArrayWriter OpenIntArray(unsigned int count);
	// Opens a <Name_array> element.
	ColladaNameArrayWriter OpenNameArray(unsigned int count);
	// Opens a <SIDREF_array> element.
	ColladaSIDREFArrayWriter OpenSIDREFArray(unsigned int count);
	// Opens a <technique_common> element.
	TechniqueCommonWriter OpenTechniqueCommon();
	// Opens a <technique> element.
	COLLADA_DECLARE_OpenTechniqueCore;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaSourceCoreWriter, const string& id);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<spline>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <spline> element.
COLLADA_ELEMENT_CLASS(ColladaSplineWriter)
{
public:
	// Sets the optional 'closed' attribute value.
	void SetClosed(bool value);

	// Opens a <source> element.
	ColladaSourceCoreWriter OpenSource(const string& id);
	// Opens a <control_vertices> element.
	ColladaControlVerticesWriter OpenControlVertices();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaSplineWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<spot>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <spot> element.
COLLADA_ELEMENT_CLASS(ColladaSpotWriter)
{
public:
	// Adds a <color> element.
	COLLADA_DECLARE_AddColor;
	// Adds a <*_attenuation> element.
	COLLADA_DECLARE_AddConstantLinearQuadraticAttenuation;
	// Adds a <falloff_angle> element.
	void AddFalloffAngle(double value, const string& sid = EmptyString);
	// Adds a <falloff_exponent> element.
	void AddFalloffExponent(double value, const string& sid = EmptyString);

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaSpotWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<targets>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <targets> element.
COLLADA_ELEMENT_CLASS(ColladaTargetsWriter)
{
public:
	// Adds an <input> element.
	COLLADA_DECLARE_AddInputUnshared;
	
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaTargetsWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<technique> (Core)
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <technique> element.
COLLADA_ELEMENT_CLASS(ColladaTechniqueCoreWriter)
{
public:
	// Sets the optional 'xmlns' attribute value.
	void SetXmlNamespace(const string& value);

	// Gets the writer object to use to write the content of the technique.
	XmlFileWriter* GetWriter();

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaTechniqueCoreWriter, const string& profile);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<triangles>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <triangles> element.
COLLADA_ELEMENT_CLASS(ColladaTrianglesWriter)
{
public:
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;
	// Sets the optional 'material' attribute value.
	void SetMaterial(const string& value);

	// Adds an <input> element.
	COLLADA_DECLARE_AddInputShared;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Adds a <p> element.
	COLLADA_DECLARE_Indices;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaTrianglesWriter, unsigned int count);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<trifans>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <trifans> element.
COLLADA_ELEMENT_CLASS(ColladaTriFansWriter)
{
public:
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;
	// Sets the optional 'material' attribute value.
	void SetMaterial(const string& value);

	// Adds an <input> element.
	COLLADA_DECLARE_AddInputShared;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Adds a <p> element.
	COLLADA_DECLARE_Indices;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaTriFansWriter, unsigned int count);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<tristrips>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <tristrips> element.
COLLADA_ELEMENT_CLASS(ColladaTriStripsWriter)
{
public:
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;
	// Sets the optional 'material' attribute value.
	void SetMaterial(const string& value);

	// Adds an <input> element.
	COLLADA_DECLARE_AddInputShared;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Adds a <p> element.
	COLLADA_DECLARE_Indices;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaTriStripsWriter, unsigned int count);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<vertex_weights>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <vertex_weights> element.
COLLADA_ELEMENT_CLASS(ColladaVertexWeightsWriter)
{
public:
	// Adds an <input> element.
	COLLADA_DECLARE_AddInputShared;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Adds a <vcount> element.
	COLLADA_DECLARE_VCount;
	// Adds a <p> element.
	COLLADA_DECLARE_Indices;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaVertexWeightsWriter, unsigned int count);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<vertices>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <vertices> element.
COLLADA_ELEMENT_CLASS(ColladaVerticesWriter)
{
public:
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Adds an <input> element.
	COLLADA_DECLARE_AddInputUnshared;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaVerticesWriter, const string& id);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<visual_scene>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <visual_scene> element.
COLLADA_ELEMENT_CLASS(ColladaVisualSceneWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <node> element.
	ColladaNodeWriter OpenNode();
	// Opens an <evaluate_scene> element.
	ColladaEvaluateSceneWriter OpenEvaluateScene();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaVisualSceneWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<attachment>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <attachment> element.
COLLADA_ELEMENT_CLASS(ColladaAttachmentWriter)
{
public:
	// Adds a <translate> element.
	COLLADA_DECLARE_AddTranslate;
	// Adds a <rotate> element.
	COLLADA_DECLARE_AddRotate;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaAttachmentWriter, const string& rigidBody);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<box>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <box> element.
COLLADA_ELEMENT_CLASS(ColladaBoxWriter)
{
public:
	// Adds a <half_extents> element.
	void AddHalfExtents(double x, double y, double z);

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaBoxWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<capsule>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <capsule> element.
COLLADA_ELEMENT_CLASS(ColladaCapsuleWriter)
{
public:
	// Adds a <height> element.
	void AddHeight(double value);
	// Adds a <radius> element.
	void AddRadius(double value);

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaCapsuleWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<convex_mesh>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <convex_mesh> element.
COLLADA_ELEMENT_CLASS(ColladaConvexMeshWriter)
{
public:
	// Sets the optional 'convex_hull_of' attribute value.
	void SetConvexHullOf(const string& value);

	// Opens a <source> element.
	ColladaSourceCoreWriter OpenSource(const string& id);
	// Opens a <vertices> element.
	ColladaVerticesWriter OpenVertices(const string& id);
	// Opens a <lines> element.
	ColladaLinesWriter OpenLines(unsigned int count);
	// Opens a <linestrips> element.
	ColladaLineStripsWriter OpenLineStrips(unsigned int count);
	// Opens a <polygons> element.
	ColladaPolygonsWriter OpenPolygons(unsigned int count);
	// Opens a <polylist> element.
	ColladaPolyListWriter OpenPolyList(unsigned int count);
	// Opens a <triangles> element.
	ColladaTrianglesWriter OpenTriangles(unsigned int count);
	// Opens a <trifans> element.
	ColladaTriFansWriter OpenTriFans(unsigned int count);
	// Opens a <tristrips> element.
	ColladaTriStripsWriter OpenTriStrips(unsigned int count);
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaConvexMeshWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<cylinder>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <cylinder> element.
COLLADA_ELEMENT_CLASS(ColladaCylinderWriter)
{
public:
	// Adds a <height> element.
	void AddHeight(double value);
	// Adds a <radius> element.
	void AddRadius(double value);

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaCylinderWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<force_field>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <force_field> element.
COLLADA_ELEMENT_CLASS(ColladaForceFieldWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <technique> element.
	COLLADA_DECLARE_OpenTechniqueCore;
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaForceFieldWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<instance_force_field>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <instance_force_field> element.
COLLADA_ELEMENT_CLASS(ColladaInstanceForceFieldWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaInstanceForceFieldWriter, const string& url);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<instance_physics_material>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <instance_physics_material> element.
COLLADA_ELEMENT_CLASS(ColladaInstancePhysicsMaterialWriter)
{
public:
	// Sets the optional 'sid' attribute value.
	COLLADA_DECLARE_SetSID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaInstancePhysicsMaterialWriter, const string& url);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<instance_physics_model>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <instance_physics_model> element.
COLLADA_ELEMENT_CLASS(ColladaInstancePhysicsModelWriter)
{
public:
	// Sets the optional 'sid' attribute value.
	COLLADA_DECLARE_SetSID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;
	// Sets the optional 'parent' attribute value.
	void SetParent(const string& value);

	// Opens an <instance_force_field> element.
	ColladaInstanceForceFieldWriter OpenInstanceForceField(const string& url);
	// Opens an <instance_rigid_body> element.
	ColladaInstanceRigidBodyWriter OpenInstanceRigidBody(const string& body, const string& target);
	// Opens an <instance_rigid_constraint> element.
	ColladaInstanceRigidConstraintWriter OpenInstanceRigidConstraint(const string& constraint);
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaInstancePhysicsModelWriter, const string& url);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<instance_physics_scene>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <instance_physics_scene> element.
COLLADA_ELEMENT_CLASS(ColladaInstancePhysicsSceneWriter)
{
public:
	// Sets the optional 'sid' attribute value.
	COLLADA_DECLARE_SetSID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaInstancePhysicsSceneWriter, const string& url);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<instance_rigid_body>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <instance_rigid_body> element.
COLLADA_ELEMENT_CLASS(ColladaInstanceRigidBodyWriter)
{
public:
	// Writes a <technique_common> element.
	COLLADA_ELEMENT_CLASS(TechniqueCommonWriter)
	{
	public:
		// Writes a <mass_frame> element.
		COLLADA_ELEMENT_CLASS(MassFrameWriter)
		{
		public:
			// Adds a <translate> element.
			COLLADA_DECLARE_AddTranslate;
			// Adds a <rotate> element.
			COLLADA_DECLARE_AddRotate;

			// Constructor.
			COLLADA_ELEMENT_CTOR(MassFrameWriter);
		};

		// Adds an <angular_velocity> element.
		void AddAngularVelocity(double x, double y, double z);
		// Adds a <velocity> element.
		void AddVelocity(double x, double y, double z);
		// Adds a <dynamic> element.
		void AddDynamic(bool value, const string& sid = EmptyString);
		// Adds a <mass> element.
		void AddMass(double value, const string& sid = EmptyString);
		// Adds an <inertia> element.
		void AddInertia(double x, double y, double z, const string& sid = EmptyString);

		// Opens a <mass_frame> element.
		MassFrameWriter OpenMassFrame();
		// Opens a <physics_material> element.
		ColladaPhysicsMaterialWriter OpenPhysicsMaterial();
		// Opens an <instance_physics_material> element.
		ColladaInstancePhysicsMaterialWriter OpenInstancePhysicsMaterial(const string& url);
		// Opens a <shape> element.
		ColladaShapeWriter OpenShape();

		// Constructor.
		COLLADA_ELEMENT_CTOR(TechniqueCommonWriter);
	};

	// Sets the optional 'sid' attribute value.
	COLLADA_DECLARE_SetSID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens a <technique_common> element.
	TechniqueCommonWriter OpenTechniqueCommon();
	// Opens a <technique> element.
	COLLADA_DECLARE_OpenTechniqueCore;
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaInstanceRigidBodyWriter, const string& body, const string& target);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<instance_rigid_constraint>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <instance_rigid_constraint> element.
COLLADA_ELEMENT_CLASS(ColladaInstanceRigidConstraintWriter)
{
public:
	// Sets the optional 'sid' attribute value.
	COLLADA_DECLARE_SetSID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaInstanceRigidConstraintWriter, const string& constraint);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<library_force_fields>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <library_force_fields> element.
COLLADA_ELEMENT_CLASS(ColladaLibraryForceFieldsWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <force_field> element.
	ColladaForceFieldWriter OpenForceField();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaLibraryForceFieldsWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<library_physics_materials>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <library_physics_materials> element.
COLLADA_ELEMENT_CLASS(ColladaLibraryPhysicsMaterialsWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <physics_material> element.
	ColladaPhysicsMaterialWriter OpenPhysicsMaterial();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaLibraryPhysicsMaterialsWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<library_physics_models>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <library_physics_models> element.
COLLADA_ELEMENT_CLASS(ColladaLibraryPhysicsModelsWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <physics_model> element.
	ColladaPhysicsModelWriter OpenPhysicsModel();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaLibraryPhysicsModelsWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<library_physics_scenes>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <library_physics_scenes> element.
COLLADA_ELEMENT_CLASS(ColladaLibraryPhysicsScenesWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <physics_scene> element.
	ColladaPhysicsSceneWriter OpenPhysicsScene();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaLibraryPhysicsScenesWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<physics_material>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <physics_material> element.
COLLADA_ELEMENT_CLASS(ColladaPhysicsMaterialWriter)
{
public:
	// Writes a <technique_common> element.
	COLLADA_ELEMENT_CLASS(TechniqueCommonWriter)
	{
	public:
		// Adds a <dynamic_friction> element.
		void AddDynamicFriction(double value, const string& sid = EmptyString);
		// Adds a <restitution> element.
		void AddRestitution(double value, const string& sid = EmptyString);
		// Adds a <static_friction> element.
		void AddStaticFriction(double value, const string& sid = EmptyString);

		// Constructor.
		COLLADA_ELEMENT_CTOR(TechniqueCommonWriter);
	};

	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <technique_common> element.
	TechniqueCommonWriter OpenTechniqueCommon();
	// Opens a <technique> element.
	COLLADA_DECLARE_OpenTechniqueCore;
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaPhysicsMaterialWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<physics_model>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <physics_model> element.
COLLADA_ELEMENT_CLASS(ColladaPhysicsModelWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <rigid_body> element.
	ColladaRigidBodyWriter OpenRigidBody(const string& sid);
	// Opens a <rigid_constraint> element.
	ColladaRigidConstraintWriter OpenRigidConstraint(const string& sid);
	// Opens an <isntance_physics_model> element.
	ColladaInstancePhysicsModelWriter OpenInstancePhysicsModel(const string& url);
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaPhysicsModelWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<physics_scene>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <physics_scene> element.
COLLADA_ELEMENT_CLASS(ColladaPhysicsSceneWriter)
{
public:
	// Writes a <technique_common> element.
	COLLADA_ELEMENT_CLASS(TechniqueCommonWriter)
	{
	public:
		// Adds a <gravity> element.
		void AddGravity(double x, double y, double z, const string& sid = EmptyString);
		// Adds a <time_step> element.
		void AddTimeStep(double value, const string& sid = EmptyString);

		// Constructor.
		COLLADA_ELEMENT_CTOR(TechniqueCommonWriter);
	};

	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens an <instance_force_field> element.
	ColladaInstanceForceFieldWriter OpenInstanceForceField(const string& url);
	// Opens an <instance_physics_model> element.
	ColladaInstancePhysicsModelWriter OpenInstancePhysicsModel(const string& url);
	// Opens a <technique_common> element.
	TechniqueCommonWriter OpenTechniqueCommon();
	// Opens a <technique> element.
	COLLADA_DECLARE_OpenTechniqueCore;
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaPhysicsSceneWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<plane>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <plane> element.
COLLADA_ELEMENT_CLASS(ColladaPlaneWriter)
{
public:
	// Adds an <equation> element.
	void AddEquation(double a, double b, double c, double d);

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaPlaneWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<ref_attachment>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <ref_attachment> element.
COLLADA_ELEMENT_CLASS(ColladaRefAttachmentWriter)
{
public:
	// Adds a <translate> element.
	COLLADA_DECLARE_AddTranslate;
	// Adds a <rotate> element.
	COLLADA_DECLARE_AddRotate;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaRefAttachmentWriter, const string& rigidBody);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<rigid_body>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <rigid_body> element.
COLLADA_ELEMENT_CLASS(ColladaRigidBodyWriter)
{
public:
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;

	// Opens a <technique_common> element.
	ColladaInstanceRigidBodyWriter::TechniqueCommonWriter OpenTechniqueCommon();
	// Opens a <technique> element.
	COLLADA_DECLARE_OpenTechniqueCore;
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaRigidBodyWriter, const string& sid);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<rigid_constraint>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <rigid_constraint> element.
COLLADA_ELEMENT_CLASS(ColladaRigidConstraintWriter)
{
public:
	// Writes a <technique_common> element.
	COLLADA_ELEMENT_CLASS(TechniqueCommonWriter)
	{
	public:
		// Writes a <limits> element.
		COLLADA_ELEMENT_CLASS(LimitsWriter)
		{
		public:
			// Writes either a <swing_cone_and_twist> or a <linear> element.
			COLLADA_ELEMENT_CLASS(SwingConeAndTwistOrLinearWriter)
			{
			public:
				// Adds a <min> element.
				void AddMin(double x, double y, double z, const string& sid = EmptyString);
				// Adds a <max> element.
				void AddMax(double x, double y, double z, const string& sid = EmptyString);

				// Constructor.
				COLLADA_ELEMENT_CTOR(SwingConeAndTwistOrLinearWriter, const string& elementName);
			};

			// Opens a <swing_cone_and_twist> element.
			SwingConeAndTwistOrLinearWriter OpenSwingConeAndTwist();
			// Opens a <linear> element.
			SwingConeAndTwistOrLinearWriter OpenLinear();

			// Constructor.
			COLLADA_ELEMENT_CTOR(LimitsWriter);
		};

		// Writes a <spring> element.
		COLLADA_ELEMENT_CLASS(SpringWriter)
		{
		public:
			// Writes either a <linear> or an <angular> element.
			COLLADA_ELEMENT_CLASS(LinearOrAngularWriter)
			{
			public:
				// Adds a <stiffness> element.
				void AddStiffness(double value, const string& sid = EmptyString);
				// Adds a <damping> element.
				void AddDamping(double value, const string& sid = EmptyString);
				// Adds a <target_value> element.
				void AddTargetValue(double value, const string& sid = EmptyString);

				// Constructor.
				COLLADA_ELEMENT_CTOR(LinearOrAngularWriter, const string& elementName);
			};

			// Opens a <linear> element.
			LinearOrAngularWriter OpenLinear();
			// Opens an <angular> element.
			LinearOrAngularWriter OpenAngular();

			// Constructor.
			COLLADA_ELEMENT_CTOR(SpringWriter);
		};

		// Adds an <enabled> element.
		void AddEnabled(bool value, const string& sid = EmptyString);
		// Adds an <interpenetrate> element.
		void AddInterpenetrate(bool value, const string& sid = EmptyString);

		// Opens a <limits> element.
		LimitsWriter OpenLimits();
		// Opens a <spring> element.
		SpringWriter OpenSpring();

		// Constructor.
		COLLADA_ELEMENT_CTOR(TechniqueCommonWriter);
	};

	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens a <ref_attachment> element.
	ColladaRefAttachmentWriter OpenRefAttachment(const string& rigidBody);
	// Opens an <attachment> element.
	ColladaAttachmentWriter OpenAttachment(const string& rigidBody);
	// Opens a <technique_common> element.
	TechniqueCommonWriter OpenTechniqueCommon();
	// Opens a <technique> element.
	COLLADA_DECLARE_OpenTechniqueCore;
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaRigidConstraintWriter, const string& sid);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<shape>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <shape> element.
COLLADA_ELEMENT_CLASS(ColladaShapeWriter)
{
public:
	// Adds a <hollow> element.
	void AddHollow(bool value, const string& sid = EmptyString);
	// Adds a <mass> element.
	void AddMass(double value, const string& sid = EmptyString);
	// Adds a <density> element.
	void AddDensity(double value, const string& sid = EmptyString);
	// Adds a <rotate> element.
	COLLADA_DECLARE_AddRotate;
	// Adds a <translate> element.
	COLLADA_DECLARE_AddTranslate;

	// Opens a <physics_material> element.
	ColladaPhysicsMaterialWriter OpenPhysicsMaterial();
	// Opens an <instance_physics_material> element.
	ColladaInstancePhysicsMaterialWriter OpenInstancePhysicsMaterial(const string& url);
	// Opens a <plane> element.
	ColladaPlaneWriter OpenPlane();
	// Opens a <box> element.
	ColladaBoxWriter OpenBox();
	// Opens a <sphere> element.
	ColladaSphereWriter OpenSphere();
	// Opens a <cylinder> element.
	ColladaCylinderWriter OpenCylinder();
	// Opens a <capsule> element.
	ColladaCapsuleWriter OpenCapsule();
	// Opens an <instance_geometry> element.
	ColladaInstanceGeometryWriter OpenInstanceGeometry(const string& url);
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaShapeWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<sphere>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <sphere> element.
COLLADA_ELEMENT_CLASS(ColladaSphereWriter)
{
public:
	// Adds a <radius> element.
	void AddRadius(double value);

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaSphereWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<alpha>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <alpha> element.
COLLADA_ELEMENT_CLASS(ColladaAlphaWriter)
{
public:
	// Sets the optional 'operator' attribute value.
	void SetOperator(ColladaTexCombinerOperator::Type value);
	// Sets the optional 'scale' attribute value.
	void SetScale(float value);

	// Adds an <argument> element.
	void AddArgument(ColladaTexCombinerSource::Type source = ColladaTexCombinerSource::Undefined, ColladaTexCombinerOperand::Type operand = ColladaTexCombinerOperand::Undefined, const string& sampler = EmptyString);

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaAlphaWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<annotate>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <annotate> element.
COLLADA_ELEMENT_CLASS(ColladaAnnotateWriter)
{
public:
	// Adds a <bool> element.
	void AddBool(bool x);
	// Adds a <bool2> element.
	void AddBool2(bool x, bool y);
	// Adds a <bool3> element.
	void AddBool3(bool x, bool y, bool z);
	// Adds a <bool4> element.
	void AddBool4(bool x, bool y, bool z, bool w);
	// Adds an <int> element.
	void AddInt(int x);
	// Adds an <int2> element.
	void AddInt2(int x, int y);
	// Adds an <int3> element.
	void AddInt3(int x, int y, int z);
	// Adds an <int4> element.
	void AddInt4(int x, int y, int z, int w);
	// Adds a <float> element.
	void AddFloat(float x);
	// Adds a <float2> element.
	void AddFloat2(float x, float y);
	// Adds a <float3> element.
	void AddFloat3(float x, float y, float z);
	// Adds a <float4> element.
	void AddFloat4(float x, float y, float z, float w);
	// Adds a <float2x2> element.
	void AddFloat2x2(float m11, float m12, float m21, float m22);
	// Adds a <float3x3> element.
	void AddFloat3x3(float m11, float m12, float m13, float m21, float m22, float m23, float m31, float m32, float m33);
	// Adds a <float4x4> element.
	void AddFloat4x4(float m11, float m12, float m13, float m14, float m21, float m22, float m23, float m24, float m31, float m32, float m33, float m34, float m41, float m42, float m43, float m44);
	// Adds a <string>
	void AddString(const string& value);

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaAnnotateWriter, const string& name);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<array>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <array> element.
COLLADA_ELEMENT_CLASS(ColladaArrayWriter)
{
public:
	// TODO: <array> (FX)

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaArrayWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<binary>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <binary> element.
COLLADA_ELEMENT_CLASS(ColladaBinaryWriter)
{
public:
	// Adds a <ref> element.
	void AddRef(const string& value);

	// Opens a <hex> element.
	void OpenHex(const string& format = EmptyString);
	// Appends bytes in hexadecimal form into the <hex> element.
	void AppendBytes(unsigned char* values, int count);
	// Closes the <hex> element.
	void CloseHex();

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaBinaryWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<bind_material>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <bind_material> element.
COLLADA_ELEMENT_CLASS(ColladaBindMaterialWriter)
{
public:
	// Writes a <technique_common> element.
	COLLADA_ELEMENT_CLASS(TechniqueCommonWriter)
	{
	public:
		// Opens an <instance_material> element.
		ColladaInstanceMaterialGeometryWriter OpenInstanceMaterial(const string& target, const string& symbol);

		// Constructor.
		COLLADA_ELEMENT_CTOR(TechniqueCommonWriter);
	};

	// Adds a <param> element.
	COLLADA_DECLARE_AddParam;

	// Opens a <technique_common> element.
	TechniqueCommonWriter OpenTechniqueCommon();
	// Opens a <technique> element.
	COLLADA_DECLARE_OpenTechniqueCore;
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaBindMaterialWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<bind_uniform>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <bind_uniform> element.
COLLADA_ELEMENT_CLASS(ColladaBindUniformWriter)
{
public:
	// TODO: <bind_uniform>

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaBindUniformWriter, const string& symbol);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<blinn>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <blinn> element.
COLLADA_ELEMENT_CLASS(ColladaBlinnWriter)
{
public:
	// Opens an <emission> element.
	ColladaFXCommonColorOrTextureWriter OpenEmission();
	// Opens an <ambient> element.
	ColladaFXCommonColorOrTextureWriter OpenAmbient();
	// Opens a <diffuse> element.
	ColladaFXCommonColorOrTextureWriter OpenDiffuse();
	// Opens a <specular> element.
	ColladaFXCommonColorOrTextureWriter OpenSpecular();
	// Opens a <shininess> element.
	ColladaFXCommonFloatOrParamWriter OpenShininess();
	// Opens a <reflective> element.
	ColladaFXCommonColorOrTextureWriter OpenReflective();
	// Opens a <reflectivity> element.
	ColladaFXCommonFloatOrParamWriter OpenReflectivity();
	// Opens a <transparent> element.
	ColladaFXCommonColorOrTextureWriter OpenTransparent();
	// Opens a <transparency> element.
	ColladaFXCommonFloatOrParamWriter OpenTransparency();
	// Opens a <index_of_refraction> element.
	ColladaFXCommonFloatOrParamWriter OpenIndexOfRefraction();

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaBlinnWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<color_target>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <color_target> element.
COLLADA_ELEMENT_CLASS(ColladaColorTargetWriter)
{
public:
	// Sets the optional 'index' attribute value.
	void SetIndex(unsigned int value);
	// Sets the optional 'slice' attribute value.
	void SetSlice(unsigned int value);
	// Sets the optional 'mip' attribute value.
	void SetMip(unsigned int value);
	// Sets the optional 'face' attribute value.
	void SetFace(ColladaCubeFace::Type value);

	// Adds a <param> element.
	void AddParam(const string& ref);

	// Opens an <instance_image> element.
	ColladaInstanceImageWriter OpenInstanceImage(const string& url);

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaColorTargetWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<compiler>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <compiler> element.
COLLADA_ELEMENT_CLASS(ColladaCompilerWriter)
{
public:
	// Sets the optional 'target' attribute value.
	void SetTarget(const string& value);
	// Sets the optional 'options' attribute value.
	void SetOptions(const string& value);

	// Opens a <binary> element.
	ColladaBinaryWriter OpenBinary();

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaCompilerWriter, const string& platform);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<constant> (FX)
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <constant> element.
COLLADA_ELEMENT_CLASS(ColladaConstantFXWriter)
{
public:
	// Opens an <emission> element.
	ColladaFXCommonColorOrTextureWriter OpenEmission();
	// Opens a <reflective> element.
	ColladaFXCommonColorOrTextureWriter OpenReflective();
	// Opens a <reflectivity> element.
	ColladaFXCommonFloatOrParamWriter OpenReflectivity();
	// Opens a <transparent> element.
	ColladaFXCommonColorOrTextureWriter OpenTransparent();
	// Opens a <transparency> element.
	ColladaFXCommonFloatOrParamWriter OpenTransparency();
	// Opens a <index_of_refraction> element.
	ColladaFXCommonFloatOrParamWriter OpenIndexOfRefraction();

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaConstantFXWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<create_2d>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <create_2d> element.
COLLADA_ELEMENT_CLASS(ColladaCreate2DWriter)
{
public:
	// Adds a <size_exact> element.
	void AddSizeExact(unsigned int width, unsigned int height);
	// Adds a <size_ratio> element.
	void AddSizeRatio(double width, double height);
	// Adds a <mips> element.
	void AddMips(unsigned int levels, bool autoGenerate);
	// Adds an <unnormalized> element.
	void AddUnnormalized();
	// Adds an <array> element.
	void AddArray(unsigned int length, bool resizable = false);

	// Opens a <format> element.
	ColladaFormatWriter OpenFormat();
	// Opens an <init_from> element.
	ColladaInitFromWriter OpenInitFrom();

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaCreate2DWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<create_3d>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <create_3d> element.
COLLADA_ELEMENT_CLASS(ColladaCreate3DWriter)
{
public:
	// Adds a <size> element.
	void AddSize(unsigned int width, unsigned int height, unsigned int depth);
	// Adds a <mips> element.
	void AddMips(unsigned int levels, bool autoGenerate);
	// Adds an <array> element.
	void AddArray(unsigned int length, bool resizable = false);

	// Opens a <format> element.
	ColladaFormatWriter OpenFormat();
	// Opens an <init_from> element.
	ColladaInitFromWriter OpenInitFrom();

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaCreate3DWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<create_cube>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <create_cube> element.
COLLADA_ELEMENT_CLASS(ColladaCreateCubeWriter)
{
public:
	// Adds a <size> element.
	void AddSize(unsigned int width);
	// Adds a <mips> element.
	void AddMips(unsigned int levels, bool autoGenerate);
	// Adds an <array> element.
	void AddArray(unsigned int length, bool resizable = false);

	// Opens a <format> element.
	ColladaFormatWriter OpenFormat();
	// Opens an <init_from> element.
	ColladaInitFromWriter OpenInitFrom();

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaCreateCubeWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<depth_target>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <depth_target> element.
COLLADA_ELEMENT_CLASS(ColladaDepthTargetWriter)
{
public:
	// Sets the optional 'index' attribute value.
	void SetIndex(unsigned int value);
	// Sets the optional 'slice' attribute value.
	void SetSlice(unsigned int value);
	// Sets the optional 'mip' attribute value.
	void SetMip(unsigned int value);
	// Sets the optional 'face' attribute value.
	void SetFace(ColladaCubeFace::Type value);

	// Adds a <param> element.
	void AddParam(const string& ref);

	// Opens an <instance_image> element.
	ColladaInstanceImageWriter OpenInstanceImage(const string& url);

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaDepthTargetWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<effect>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <effect> element.
COLLADA_ELEMENT_CLASS(ColladaEffectWriter)
{
public:
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens an <annotate> element.
	ColladaAnnotateWriter OpenAnnotate(const string& name);
	// Opens a <newparam> element.
	ColladaNewParamFXWriter OpenNewParam(const string& sid);
	// Opens an <annotate> element.
	ColladaProfileBRIDGEWriter OpenProfileBRIDGE(const string& url);
	// Opens an <annotate> element.
	ColladaProfileCGWriter OpenProfileCG();
	// Opens an <annotate> element.
	ColladaProfileGLESWriter OpenProfileGLES();
	// Opens an <annotate> element.
	ColladaProfileGLES2Writer OpenProfileGLES2(const string& language);
	// Opens an <annotate> element.
	ColladaProfileGLSLWriter OpenProfileGLSL();
	// Opens an <annotate> element.
	ColladaProfileCOMMONWriter OpenProfileCommon();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaEffectWriter, const string& id);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<evaluate>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <evaluate> element.
COLLADA_ELEMENT_CLASS(ColladaEvaluateWriter)
{
public:
	// Adds a <color_clear> element.
	void AddColorClear(float r, float g, float b, float a, unsigned int index = 0);
	// Adds a <depth_clear> element.
	void AddDepthClear(float value, unsigned int index = 0);
	// Adds a <stencil_clear> element.
	void AddStencilClear(unsigned char value, unsigned int index = 0);
	// Adds a <draw> element.
	void AddDraw(ColladaDrawParameter::Type value);
	// Adds a <draw> element.
	void AddDraw(const string& value);

	// Opens a <color_target> element.
	ColladaColorTargetWriter OpenColorTarget();
	// Opens a <depth_target> element.
	ColladaDepthTargetWriter OpenDepthTarget();
	// Opens a <stencil_target> element.
	ColladaStencilTargetWriter OpenStencilTarget();

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaEvaluateWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<format>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <format> element.
COLLADA_ELEMENT_CLASS(ColladaFormatWriter)
{
public:
	// Adds a <hint> element.
	void AddHint(ColladaFormatChannels::Type channels, ColladaFormatRange::Type range, ColladaFormatPrecision::Type precision = ColladaFormatPrecision::Undefined, const string& space = EmptyString);
	// Adds an <exact> element.
	void AddExact(const string& value);

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaFormatWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<fx_common_color_or_texture_type>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <fx_common_color_or_texture_type> element.
COLLADA_ELEMENT_CLASS(ColladaFXCommonColorOrTextureWriter)
{
public:
	// Writes a <texture> element.
	COLLADA_ELEMENT_CLASS(TextureWriter)
	{
	public:
		// Opens an <extra> element.
		COLLADA_DECLARE_OpenExtra;

		// Constructor.
		COLLADA_ELEMENT_CTOR(TextureWriter, const string& texture, const string& texcoord);
	};

	// Sets the optional 'opaque' attribute.
	void SetOpaque(ColladaOpaqueMode::Type value);

	// Adds a <param> element.
	void AddParam(const string& ref);
	// Adds a <color> element.
	COLLADA_DECLARE_AddColor;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaFXCommonColorOrTextureWriter, const string& elementName);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<fx_common_float_or_param_type>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <fx_common_float_or_param_type> element.
COLLADA_ELEMENT_CLASS(ColladaFXCommonFloatOrParamWriter)
{
public:
	// Adds a <float> element.
	void AddFloat(double value, const string& sid = EmptyString);
	// Adds a <param> element.
	void AddParam(const string& ref);

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaFXCommonFloatOrParamWriter, const string& elementName);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<fx_sampler_common>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <fx_sampler_common> element.
COLLADA_ELEMENT_CLASS(ColladaFXSamplerCommonWriter)
{
public:
	// Adds a <texcoord> element.
	void AddTexcoord(const string& semantic);
	// Adds a <wrap_s> element.
	void AddWrapS(ColladaTextureWrapMode::Type value);
	// Adds a <wrap_t> element.
	void AddWrapT(ColladaTextureWrapMode::Type value);
	// Adds a <wrap_p> element.
	void AddWrapP(ColladaTextureWrapMode::Type value);
	// Adds a <minfilter> element.
	void AddMinFilter(ColladaTextureFilter::Type value);
	// Adds a <magfilter> element.
	void AddMagFilter(ColladaTextureFilter::Type value);
	// Adds a <mipfilter> element.
	void AddMipFilter(ColladaTextureFilter::Type value);
	// Adds a <border_color> element.
	void AddBorderColor(double r, double g, double b, double a);
	// Adds a <mip_max_level> element.
	void AddMipMaxLevel(unsigned char value);
	// Adds a <mip_min_level> element.
	void AddMipMinLevel(unsigned char value);
	// Adds a <mip_bias> element.
	void AddMipBias(float value);
	// Adds a <max_anisotropy> element.
	void AddMaxAnisotropy(unsigned int value);

	// Opens an <instance_image> element.
	ColladaInstanceImageWriter OpenInstanceImage(const string& url);
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaFXSamplerCommonWriter, const string& elementName);
	// Factory.
	static ColladaFXSamplerCommonWriter CreateSampler1D(ColladaFileWriter& writer);
	static ColladaFXSamplerCommonWriter CreateSampler2D(ColladaFileWriter& writer);
	static ColladaFXSamplerCommonWriter CreateSampler3D(ColladaFileWriter& writer);
	static ColladaFXSamplerCommonWriter CreateSamplerCUBE(ColladaFileWriter& writer);
	static ColladaFXSamplerCommonWriter CreateSamplerDEPTH(ColladaFileWriter& writer);
	static ColladaFXSamplerCommonWriter CreateSamplerRECT(ColladaFileWriter& writer);
	static ColladaFXSamplerCommonWriter CreateSamplerStates(ColladaFileWriter& writer);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<image>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <image> element.
COLLADA_ELEMENT_CLASS(ColladaImageWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'sid' attribute value.
	COLLADA_DECLARE_SetSID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Adds a <renderable> element.
	void AddRenderable(bool share);

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens an <init_from> element.
	ColladaInitFromWriter OpenInitFrom();
	// Opens a <create_2d> element.
	ColladaCreate2DWriter OpenCreate2D();
	// Opens a <create_3d> element.
	ColladaCreate3DWriter OpenCreate3D();
	// Opens a <create_cube> element.
	ColladaCreateCubeWriter OpenCreateCube();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaImageWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<init_from>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <init_from> element.
COLLADA_ELEMENT_CLASS(ColladaInitFromWriter)
{
public:
	// Sets the optional 'mips_generate' attribute value.
	void SetMipsGenerate(bool value);
	// Sets the optional 'array_index' attribute value.
	void SetArrayIndex(unsigned int value);

	// Adds a <ref> element.
	void AddRef(const string& value);

	// Opens a <hex> element.
	void OpenHex(const string& format);
	// Appends bytes in hexadecimal form into the <hex> element.
	void AppendBytes(unsigned char* values, int count);
	// Closes the <hex> element.
	void CloseHex();

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaInitFromWriter);
	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaInitFromWriter, unsigned int mipIndex);
	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaInitFromWriter, unsigned int mipIndex, unsigned int depth);
	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaInitFromWriter, unsigned int mipIndex, ColladaCubeFace::Type face);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<instance_effect>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <instance_effect> element.
COLLADA_ELEMENT_CLASS(ColladaInstanceEffectWriter)
{
public:
	// Sets the optional 'sid' attribute value.
	COLLADA_DECLARE_SetSID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Adds a <technique_hint> element.
	void AddTechniqueHint(const string& ref, const string& platform = EmptyString, const string& profile = EmptyString);

	// Opens a <setparam> element.
	ColladaSetParamFXWriter OpenSetParam();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaInstanceEffectWriter, const string url);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<instance_image>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <instance_image> element.
COLLADA_ELEMENT_CLASS(ColladaInstanceImageWriter)
{
public:
	// Sets the optional 'sid' attribute value.
	COLLADA_DECLARE_SetSID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaInstanceImageWriter, const string& elementName, const string& url);
	// Factory.
	static ColladaInstanceImageWriter CreateInstanceImage(ColladaFileWriter& writer, const string& url);
	static ColladaInstanceImageWriter CreateSamplerImage(ColladaFileWriter& writer, const string& url);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<instance_material> (geometry)
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <instance_material> element.
COLLADA_ELEMENT_CLASS(ColladaInstanceMaterialGeometryWriter)
{
public:
	// Sets the optional 'sid' attribute value.
	COLLADA_DECLARE_SetSID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Adds a <bind> element.
	void AddBind(const string& semantic, const string& target);
	// Adds a <bind_vertex_input> element.
	void AddBindVertexInput(const string& semantic, const string& inputSemantic, unsigned int inputSet = -1);

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaInstanceMaterialGeometryWriter, const string& target, const string& symbol);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<instance_material> (rendering)
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <instance_material> element.
COLLADA_ELEMENT_CLASS(ColladaInstanceMaterialRenderingWriter)
{
public:
	// Adds a <technique_override> element.
	void AddTechniqueOverride(const string& ref, const string& pass = EmptyString);
	// Adds a <bind> element.
	void AddBind(const string& semantic, const string& target);

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaInstanceMaterialRenderingWriter, const string& url);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<lambert>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <lambert> element.
COLLADA_ELEMENT_CLASS(ColladaLambertWriter)
{
public:
	// Opens an <emission> element.
	ColladaFXCommonColorOrTextureWriter OpenEmission();
	// Opens an <ambient> element.
	ColladaFXCommonColorOrTextureWriter OpenAmbient();
	// Opens a <diffuse> element.
	ColladaFXCommonColorOrTextureWriter OpenDiffuse();
	// Opens a <reflective> element.
	ColladaFXCommonColorOrTextureWriter OpenReflective();
	// Opens a <reflectivity> element.
	ColladaFXCommonFloatOrParamWriter OpenReflectivity();
	// Opens a <transparent> element.
	ColladaFXCommonColorOrTextureWriter OpenTransparent();
	// Opens a <transparency> element.
	ColladaFXCommonFloatOrParamWriter OpenTransparency();
	// Opens a <index_of_refraction> element.
	ColladaFXCommonFloatOrParamWriter OpenIndexOfRefraction();

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaLambertWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<library_effects>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <library_effects> element.
COLLADA_ELEMENT_CLASS(ColladaLibraryEffectsWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens an <effect> element.
	ColladaEffectWriter OpenEffect(const string& id);
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaLibraryEffectsWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<library_images>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <library_images> element.
COLLADA_ELEMENT_CLASS(ColladaLibraryImagesWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens an <image> element.
	ColladaImageWriter OpenImage();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaLibraryImagesWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<library_materials>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <library_materials> element.
COLLADA_ELEMENT_CLASS(ColladaLibraryMaterialsWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <material> element.
	ColladaMaterialWriter OpenMaterial();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaLibraryMaterialsWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<linker>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <linker> element.
COLLADA_ELEMENT_CLASS(ColladaLinkerWriter)
{
public:
	// Sets the optional 'target' attribute value.
	void SetTarget(const string& value);
	// Sets the optional 'options' attribute value.
	void SetOptions(const string& value);

	// Opens a <binary> element.
	ColladaBinaryWriter OpenBinary();

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaLinkerWriter, const string& platform);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<material>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <material> element.
COLLADA_ELEMENT_CLASS(ColladaMaterialWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens an <instance_effect> element.
	ColladaInstanceEffectWriter OpenInstanceEffect(const string& url);
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaMaterialWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<pass>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <pass> element.
COLLADA_ELEMENT_CLASS(ColladaPassWriter)
{
public:
	// Sets the optional 'sid' attribute value.
	COLLADA_DECLARE_SetSID;

	// Opens an <annotate> element.
	ColladaAnnotateWriter OpenAnnotate(const string& name);
	// Opens a <state> element.
	ColladaStatesWriter OpenStates();
	// Opens a <program> element.
	ColladaProgramWriter OpenProgram();
	// Opens an <evaluate> element.
	ColladaEvaluateWriter OpenEvaluate();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaPassWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<phong>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <phong> element.
COLLADA_ELEMENT_CLASS(ColladaPhongWriter)
{
public:
	// Opens an <emission> element.
	ColladaFXCommonColorOrTextureWriter OpenEmission();
	// Opens an <ambient> element.
	ColladaFXCommonColorOrTextureWriter OpenAmbient();
	// Opens a <diffuse> element.
	ColladaFXCommonColorOrTextureWriter OpenDiffuse();
	// Opens a <specular> element.
	ColladaFXCommonColorOrTextureWriter OpenSpecular();
	// Opens a <shininess> element.
	ColladaFXCommonFloatOrParamWriter OpenShininess();
	// Opens a <reflective> element.
	ColladaFXCommonColorOrTextureWriter OpenReflective();
	// Opens a <reflectivity> element.
	ColladaFXCommonFloatOrParamWriter OpenReflectivity();
	// Opens a <transparent> element.
	ColladaFXCommonColorOrTextureWriter OpenTransparent();
	// Opens a <transparency> element.
	ColladaFXCommonFloatOrParamWriter OpenTransparency();
	// Opens a <index_of_refraction> element.
	ColladaFXCommonFloatOrParamWriter OpenIndexOfRefraction();

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaPhongWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<profile_BRIDGE>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <profile_BRIDGE> element.
COLLADA_ELEMENT_CLASS(ColladaProfileBRIDGEWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'platform' attribute value.
	void SetPlatform(const string& value);

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaProfileBRIDGEWriter, const string& url);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<profile_CG>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <profile_CG> element.
COLLADA_ELEMENT_CLASS(ColladaProfileCGWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'platform' attribute value.
	void SetPlatform(const string& value);

	// Adds a <code> element.
	void AddCode(const string& code, const string& sid = EmptyString);
	// Adds an <include> element.
	void AddInclude(const string& sid, const string& url);

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <newparam> element.
	ColladaNewParamFXWriter OpenNewParam(const string& sid);
	// Opens a <technique> element.
	ColladaTechniqueFXWriter OpenTechnique(const string& sid);
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaProfileCGWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<profile_COMMON>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <profile_COMMON> element.
COLLADA_ELEMENT_CLASS(ColladaProfileCOMMONWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <newparam> element.
	ColladaNewParamFXWriter OpenNewParam(const string& sid);
	// Opens a <technique> element.
	ColladaTechniqueFXWriter OpenTechnique(const string& sid);
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaProfileCOMMONWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<profile_GLES>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <profile_GLES> element.
COLLADA_ELEMENT_CLASS(ColladaProfileGLESWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'platform' attribute value.
	void SetPlatform(const string& value);

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <newparam> element.
	ColladaNewParamFXWriter OpenNewParam(const string& sid);
	// Opens a <technique> element.
	ColladaTechniqueFXWriter OpenTechnique(const string& sid);
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaProfileGLESWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<profile_GLES2>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <profile_GLES2> element.
COLLADA_ELEMENT_CLASS(ColladaProfileGLES2Writer)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'platform' attribute value.
	void SetPlatform(const string& value);

	// Adds a <code> element.
	void AddCode(const string& code, const string& sid = EmptyString);
	// Adds an <include> element.
	void AddInclude(const string& sid, const string& url);

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <newparam> element.
	ColladaNewParamFXWriter OpenNewParam(const string& sid);
	// Opens a <technique> element.
	ColladaTechniqueFXWriter OpenTechnique(const string& sid);
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaProfileGLES2Writer, const string& language);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<profile_GLSL>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <profile_GLSL> element.
COLLADA_ELEMENT_CLASS(ColladaProfileGLSLWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'platform' attribute value.
	void SetPlatform(const string& value);

	// Adds a <code> element.
	void AddCode(const string& code, const string& sid = EmptyString);
	// Adds an <include> element.
	void AddInclude(const string& sid, const string& url);

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <newparam> element.
	ColladaNewParamFXWriter OpenNewParam(const string& sid);
	// Opens a <technique> element.
	ColladaTechniqueFXWriter OpenTechnique(const string& sid);
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaProfileGLSLWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<program>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <program> element.
COLLADA_ELEMENT_CLASS(ColladaProgramWriter)
{
public:
	// Adds a <bind_attribute> element.
	void AddBindAttribute(const string& symbol, const string& semantic);

	// Opens a <shader> element.
	ColladaShaderWriter OpenShader(ColladaShaderStage::Type stage);
	// Opens a <linker> element.
	ColladaLinkerWriter OpenLinker(const string& platform);
	// Opens a <bind_uniform> element.
	ColladaBindUniformWriter OpenBindUniform(const string& symbol);

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaProgramWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<render>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <render> element.
COLLADA_ELEMENT_CLASS(ColladaRenderWriter)
{
public:
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;
	// Sets the optional 'sid' attribute value.
	COLLADA_DECLARE_SetSID;
	// Sets the optional 'camera_node' attribute value.
	void SetCameraNode(const string& value);

	// Adds a <layer> element.
	void AddLayer(const string& layers);

	// Opens an <instance_material> element.
	ColladaInstanceMaterialRenderingWriter OpenInstanceMaterial(const string& url);
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaRenderWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<RGB>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <RGB> element.
COLLADA_ELEMENT_CLASS(ColladaRGBWriter)
{
public:
	// Sets the optional 'operator' attribute value.
	void SetOperator(ColladaTexCombinerOperator::Type value);
	// Sets the optional 'scale' attribute value.
	void SetScale(float value);

	// Adds an <argument> element.
	void AddArgument(ColladaTexCombinerSource::Type source = ColladaTexCombinerSource::Undefined, ColladaTexCombinerOperand::Type operand = ColladaTexCombinerOperand::Undefined, const string& sampler = EmptyString);

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaRGBWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<shader>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <shader> element.
COLLADA_ELEMENT_CLASS(ColladaShaderWriter)
{
public:
	// Opens a <sources> element.
	ColladaSourcesWriter OpenSources();
	// Opens a <compiler> element.
	ColladaCompilerWriter OpenCompiler(const string& platform);
	// Opens a <bind_uniform> element.
	ColladaBindUniformWriter OpenBindUniform(const string& symbol);
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaShaderWriter, ColladaShaderStage::Type stage);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<sources>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <sources> element.
COLLADA_ELEMENT_CLASS(ColladaSourcesWriter)
{
public:
	// Sets the optional 'entry' attribute value.
	void SetEntry(const string& value);

	// Adds an <inline> element.
	void AddInline(const string& value);
	// Adds an <import> element.
	void AddImport(const string& ref);

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaSourcesWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<states>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <states> element.
COLLADA_ELEMENT_CLASS(ColladaStatesWriter)
{
public:
	// Adds a new state element.
	void AddValue(const string& stateName, const string& value, int index = -1);
	void AddValue(const string& stateName, const string& value, const string& index = EmptyString);
	void AddParam(const string& stateName, const string& param, int index = -1);
	void AddParam(const string& stateName, const string& param, const string& index = EmptyString);

	// Opens a <texture_pipeline> element.
	ColladaTexturePipelineWriter OpenTexturePipeline();

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaStatesWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<stencil_target>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <stencil_target> element.
COLLADA_ELEMENT_CLASS(ColladaStencilTargetWriter)
{
public:
	// Sets the optional 'index' attribute value.
	void SetIndex(unsigned int value);
	// Sets the optional 'slice' attribute value.
	void SetSlice(unsigned int value);
	// Sets the optional 'mip' attribute value.
	void SetMip(unsigned int value);
	// Sets the optional 'face' attribute value.
	void SetFace(ColladaCubeFace::Type value);

	// Adds a <param> element.
	void AddParam(const string& ref);

	// Opens an <instance_image> element.
	ColladaInstanceImageWriter OpenInstanceImage(const string& url);

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaStencilTargetWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<technique> (FX)
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <technique> element.
COLLADA_ELEMENT_CLASS(ColladaTechniqueFXWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens an <annotate> element.
	ColladaAnnotateWriter OpenAnnotate(const string& name);
	// Opens a <blinn> element.
	ColladaBlinnWriter OpenBlinn();
	// Opens a <constant> element.
	ColladaConstantFXWriter OpenConstant();
	// Opens a <lambert> element.
	ColladaLambertWriter OpenLambert();
	// Opens a <phong> element.
	ColladaPhongWriter OpenPhong();
	// Opens a <pass> element.
	ColladaPassWriter OpenPass();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaTechniqueFXWriter, const string& sid);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<texcombiner>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <texcombiner> element.
COLLADA_ELEMENT_CLASS(ColladaTexCombinerWriter)
{
public:
	// Adds a <constant> element.
	void AddConstant(double x, double y, double z, double w);
	void AddConstant(const string& param);

	// Opens a <RGB> element.
	ColladaRGBWriter OpenRGB();
	// Opens an <alpha> element.
	ColladaAlphaWriter OpenAlpha();

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaTexCombinerWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<texenv>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <texenv> element.
COLLADA_ELEMENT_CLASS(ColladaTexEnvWriter)
{
public:
	// Sets the optional 'operator' attribute value.
	void SetOperator(ColladaTexCombinerOperator::Type value);
	// Sets the optional 'sampler' attribute value.
	void SetSampler(const string& value);

	// Adds a <constant> element.
	void AddConstant(double x, double y, double z, double w);
	void AddConstant(const string& param);

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaTexEnvWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<texture_pipeline>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <texture_pipeline> element.
COLLADA_ELEMENT_CLASS(ColladaTexturePipelineWriter)
{
public:
	// Opens a <texcombiner> element.
	ColladaTexCombinerWriter OpenTexCombiner();
	// Opens a <texenv> element.
	ColladaTexEnvWriter OpenTexEnv();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaTexturePipelineWriter);
};

// TODO: <usertype> in FX

// -------------------------------------------------------------------------------------------------------------------------------------
//		<brep>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <brep> element.
COLLADA_ELEMENT_CLASS(ColladaBRepWriter)
{
public:
	// Opens a <curves> element.
	ColladaCurvesWriter OpenCurves();
	// Opens a <surface_curves> element.
	ColladaSurfaceCurvesWriter OpenSurfaceCurves();
	// Opens a <surfaces> element.
	ColladaSurfacesWriter OpenSurfaces();
	// Opens a <source> element.
	ColladaSourceCoreWriter OpenSource(const string& id);
	// Opens a <vertices> element.
	ColladaVerticesWriter OpenVertices(const string& id);
	// Opens an <edges> element.
	ColladaEdgesWriter OpenEdges();
	// Opens a <wires> element.
	ColladaWiresWriter OpenWires(const string& id, unsigned int count);
	// Opens a <faces> element.
	ColladaFacesWriter OpenFaces();
	// Opens a <pcurves> element.
	ColladaPCurvesWriter OpenPCurves(const string& id, unsigned int count);
	// Opens a <shells> element.
	ColladaShellsWriter OpenShells(const string& id, unsigned int count);
	// Opens a <solids> element.
	ColladaSolidsWriter OpenSolids(const string& id, unsigned int count);
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaBRepWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<circle>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <circle> element.
COLLADA_ELEMENT_CLASS(ColladaCircleWriter)
{
public:
	// Adds a <radius> element.
	void AddRadius(double value);

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaCircleWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<cone>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <cone> element.
COLLADA_ELEMENT_CLASS(ColladaConeWriter)
{
public:
	// Adds a <radius> element.
	void AddRadius(double value);
	// Adds a <angle> element.
	void AddAngle(double value);

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaConeWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<curve>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <curve> element.
COLLADA_ELEMENT_CLASS(ColladaCurveWriter)
{
public:
	// Sets the optional 'sid' attribute value.
	COLLADA_DECLARE_SetSID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Adds an <orient> element.
	void AddOrient(double axisX, double axisY, double axisZ, double angle);
	// Adds an <origin> element.
	void AddOrigin(double x, double y, double z);

	// Opens a <line> element.
	ColladaLineWriter OpenLine();
	// Opens a <circle> element.
	ColladaCircleWriter OpenCircle();
	// Opens an <ellipse> element.
	ColladaEllipseWriter OpenEllipse();
	// Opens a <parabola> element.
	ColladaParabolaWriter OpenParabola();
	// Opens a <hyperbola> element.
	ColladaHyperbolaWriter OpenHyperbola();
	// Opens a <nurbs> element.
	ColladaNurbsWriter OpenNurbs(unsigned int degree);

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaCurveWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<curves>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <curves> element.
COLLADA_ELEMENT_CLASS(ColladaCurvesWriter)
{
public:
	// Opens a <curve> element.
	ColladaCurveWriter OpenCurve();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaCurvesWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<cylinder> (B-Rep)
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <cylinder> element.
COLLADA_ELEMENT_CLASS(ColladaCylinderBRepWriter)
{
public:
	// Adds a <radius> element.
	void AddRadius(double x, double y);

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaCylinderBRepWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<edges>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <edges> element.
COLLADA_ELEMENT_CLASS(ColladaEdgesWriter)
{
public:
	// Adds an <input> element.
	COLLADA_DECLARE_AddInputShared;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Adds a <p> element.
	COLLADA_DECLARE_Indices;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaEdgesWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<ellipse>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <ellipse> element.
COLLADA_ELEMENT_CLASS(ColladaEllipseWriter)
{
public:
	// Adds a <radius> element.
	void AddRadius(double x, double y);

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaEllipseWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<faces>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <faces> element.
COLLADA_ELEMENT_CLASS(ColladaFacesWriter)
{
public:
	// Adds an <input> element.
	COLLADA_DECLARE_AddInputShared;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Adds a <vcount> element.
	COLLADA_DECLARE_VCount;
	// Adds a <p> element.
	COLLADA_DECLARE_Indices;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaFacesWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<hyperbola>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <hyperbola> element.
COLLADA_ELEMENT_CLASS(ColladaHyperbolaWriter)
{
public:
	// Adds a <radius> element.
	void AddRadius(double x, double y);

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaHyperbolaWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<line>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <line> element.
COLLADA_ELEMENT_CLASS(ColladaLineWriter)
{
public:
	// Adds an <origin> element.
	void AddOrigin(double x, double y, double z);
	// Adds a <direction> element.
	void AddDirection(double x, double y, double z);

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaLineWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<nurbs>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <nurbs> element.
COLLADA_ELEMENT_CLASS(ColladaNurbsWriter)
{
public:
	// Sets the optional 'closed' attribute value.
	void SetClosed(bool value);

	// Opens a <source> element.
	ColladaSourceCoreWriter OpenSource(const string& id);
	// Opens a <control_vertices> element.
	ColladaControlVerticesWriter OpenControlVertices();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaNurbsWriter, unsigned int degree);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<nurbs_surface>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <nurbs_surface> element.
COLLADA_ELEMENT_CLASS(ColladaNurbsSurfaceWriter)
{
public:
	// Sets the optional 'closed_u' attribute value.
	void SetClosedU(bool value);
	// Sets the optional 'closed_v' attribute value.
	void SetClosedV(bool value);

	// Opens a <source> element.
	ColladaSourceCoreWriter OpenSource(const string& id);
	// Opens a <control_vertices> element.
	ColladaControlVerticesWriter OpenControlVertices();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaNurbsSurfaceWriter, unsigned int degreeU, unsigned int degreeV);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<parabola>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <parabola> element.
COLLADA_ELEMENT_CLASS(ColladaParabolaWriter)
{
public:
	// Adds a <focal> element.
	void AddFocal(double value);

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaParabolaWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<pcurves>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <pcurves> element.
COLLADA_ELEMENT_CLASS(ColladaPCurvesWriter)
{
public:
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Adds an <input> element.
	COLLADA_DECLARE_AddInputShared;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Adds a <vcount> element.
	COLLADA_DECLARE_VCount;
	// Adds a <p> element.
	COLLADA_DECLARE_Indices;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaPCurvesWriter, const string& id, unsigned int count);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<shells>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <shells> element.
COLLADA_ELEMENT_CLASS(ColladaShellsWriter)
{
public:
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Adds an <input> element.
	COLLADA_DECLARE_AddInputShared;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Adds a <vcount> element.
	COLLADA_DECLARE_VCount;
	// Adds a <p> element.
	COLLADA_DECLARE_Indices;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaShellsWriter, const string& id, unsigned int count);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<solids>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <solids> element.
COLLADA_ELEMENT_CLASS(ColladaSolidsWriter)
{
public:
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Adds an <input> element.
	COLLADA_DECLARE_AddInputShared;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Adds a <vcount> element.
	COLLADA_DECLARE_VCount;
	// Adds a <p> element.
	COLLADA_DECLARE_Indices;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaSolidsWriter, const string& id, unsigned int count);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<surface>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <surface> element.
COLLADA_ELEMENT_CLASS(ColladaSurfaceWriter)
{
public:
	// Sets the optional 'sid' attribute value.
	COLLADA_DECLARE_SetSID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Adds an <orient> element.
	void AddOrient(double axisX, double axisY, double axisZ, double angle);
	// Adds an <origin> element.
	void AddOrigin(double x, double y, double z);

	// Opens a <cone> element.
	ColladaConeWriter OpenCone();
	// Opens a <plane> element.
	ColladaPlaneWriter OpenPlane();
	// Opens a <cylinder> element.
	ColladaCylinderBRepWriter OpenCylinder();
	// Opens a <nurbs_surface> element.
	ColladaNurbsSurfaceWriter OpenNurbsSurface(unsigned int degreeU, unsigned int degreeV);
	// Opens a <sphere> element.
	ColladaSphereWriter OpenSphere();
	// Opens a <torus> element.
	ColladaTorusWriter OpenTorus();
	// Opens a <swept_surface> element.
	ColladaSweptSurfaceWriter OpenSweptSurface();

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaSurfaceWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<surfaces>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <surfaces> element.
COLLADA_ELEMENT_CLASS(ColladaSurfacesWriter)
{
public:
	// Opens a <surface> element.
	ColladaSurfaceWriter OpenSurface();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaSurfacesWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<surface_curves>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <surface_curves> element.
COLLADA_ELEMENT_CLASS(ColladaSurfaceCurvesWriter)
{
public:
	// Opens a <curve> element.
	ColladaCurveWriter OpenCurve();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaSurfaceCurvesWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<swept_surface>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <swept_surface> element.
COLLADA_ELEMENT_CLASS(ColladaSweptSurfaceWriter)
{
public:
	// Adds a <direction> element.
	void AddDirection(double x, double y, double z);
	// Adds a <origin> element.
	void AddOrigin(double x, double y, double z);
	// Adds a <axis> element.
	void AddAxis(double x, double y, double z);

	// Opens a <curve> element.
	ColladaCurveWriter OpenCurve();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaSweptSurfaceWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<torus>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <torus> element.
COLLADA_ELEMENT_CLASS(ColladaTorusWriter)
{
public:
	// Adds a <radius> element.
	void AddRadius(double x, double y);

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaTorusWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<wires>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <wires> element.
COLLADA_ELEMENT_CLASS(ColladaWiresWriter)
{
public:
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;
	
	// Adds an <input> element.
	COLLADA_DECLARE_AddInputShared;
	
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;
	
	// Adds a <vcount> element.
	COLLADA_DECLARE_VCount;
	// Adds a <p> element.
	COLLADA_DECLARE_Indices;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaWiresWriter, const string& id, unsigned int count);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<articulated_system>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <articulated_system> element.
COLLADA_ELEMENT_CLASS(ColladaArticulatedSystemWriter)
{
public:
	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <kinematics> element.
	ColladaKinematicsWriter OpenKinematics();
	// Opens a <motion> element.
	ColladaMotionWriter OpenMotion();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaArticulatedSystemWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<attachment_end>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <attachment_end> element.
COLLADA_ELEMENT_CLASS(ColladaAttachmentEndWriter)
{
public:
	// Adds a <translate> element.
	COLLADA_DECLARE_AddTranslate;
	// Adds a <rotate> element.
	COLLADA_DECLARE_AddRotate;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaAttachmentEndWriter, const string& joint);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<attachment_full>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <attachment_full> element.
COLLADA_ELEMENT_CLASS(ColladaAttachmentFullWriter)
{
public:
	// Adds a <rotate> element.
	COLLADA_DECLARE_AddRotate;
	// Adds a <translate> element.
	COLLADA_DECLARE_AddTranslate;

	// Opens a <link> element.
	ColladaLinkWriter OpenLink();

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaAttachmentFullWriter, const string& joint);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<attachment_start>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <attachment_start> element.
COLLADA_ELEMENT_CLASS(ColladaAttachmentStartWriter)
{
public:
	// Adds a <translate> element.
	COLLADA_DECLARE_AddTranslate;
	// Adds a <rotate> element.
	COLLADA_DECLARE_AddRotate;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaAttachmentStartWriter, const string& joint);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<axis_info>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <axis_info> element.
COLLADA_ELEMENT_CLASS(ColladaAxisInfoWriter)
{
public:
	// Sets the optional 'sid' attribute value.
	COLLADA_DECLARE_SetSID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// TODO: <axis_info>

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaAxisInfoWriter, const string& axis);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<bind_joint_axis>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <bind_joint_axis> element.
COLLADA_ELEMENT_CLASS(ColladaBindJointAxisWriter)
{
public:
	// Sets the optional 'target' attribute value.
	void SetTarget(const string& value);

	// TODO: <bind_joint_axis>

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaBindJointAxisWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<bind_kinematics_model>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <bind_kinematics_model> element.
COLLADA_ELEMENT_CLASS(ColladaBindKinematicsModelWriter)
{
public:
	// TODO: <bind_kinematics_model>

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaBindKinematicsModelWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<effector_info>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes an <effector_info> element.
COLLADA_ELEMENT_CLASS(ColladaEffectorInfoWriter)
{
public:
	// TODO: <effector_info>

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaEffectorInfoWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<frame_*>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <frame_*> element.
COLLADA_ELEMENT_CLASS(ColladaKinematicsFrameWriter)
{
public:
	// TODO: <frame_*>

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaKinematicsFrameWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<instance_articulated_system>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <instance_articulated_system> element.
COLLADA_ELEMENT_CLASS(ColladaInstanceArticulatedSystemWriter)
{
public:
	// Sets the optional 'sid' attribute value.
	COLLADA_DECLARE_SetSID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Adds a <bind> element.
	COLLADA_DECLARE_AddBindKinematics;

	// TODO: <instance_articulated_system>

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaInstanceArticulatedSystemWriter, const string& url);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<instance_joint>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <instance_joint> element.
COLLADA_ELEMENT_CLASS(ColladaInstanceJointWriter)
{
public:
	// Sets the optional 'sid' attribute value.
	COLLADA_DECLARE_SetSID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaInstanceJointWriter, const string& url);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<instance_kinematics_model>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <instance_kinematics_model> element.
COLLADA_ELEMENT_CLASS(ColladaInstanceKinematicsModelWriter)
{
public:
	// Sets the optional 'sid' attribute value.
	COLLADA_DECLARE_SetSID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// TODO: <instance_kinematics_model>

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaInstanceKinematicsModelWriter, const string& url);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<instance_kinematics_scene>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <instance_kinematics_scene> element.
COLLADA_ELEMENT_CLASS(ColladaInstanceKinematicsSceneWriter)
{
public:
	// Sets the optional 'sid' attribute value.
	COLLADA_DECLARE_SetSID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// TODO: <instance_kinematics_scene>

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaInstanceKinematicsSceneWriter, const string& url);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<joint>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <joint> element.
COLLADA_ELEMENT_CLASS(ColladaJointWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'sid' attribute value.
	COLLADA_DECLARE_SetSID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens a <prismatic> element.
	ColladaPrismaticWriter OpenPrismatic();
	// Opens a <revolute> element.
	ColladaRevoluteWriter OpenRevolute();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaJointWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<kinematics>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <kinematics> element.
COLLADA_ELEMENT_CLASS(ColladaKinematicsWriter)
{
public:
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// TODO: <kinematics>

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaKinematicsWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<kinematics_model>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <kinematics_model> element.
COLLADA_ELEMENT_CLASS(ColladaKinematicsModelWriter)
{
public:
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// TODO: <kinematics_model>

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaKinematicsModelWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<kinematics_scene>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <kinematics_scene> element.
COLLADA_ELEMENT_CLASS(ColladaKinematicsSceneWriter)
{
public:
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// TODO: <kinematics_scene>

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaKinematicsSceneWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<library_articulated_systems>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <library_articulated_systems> element.
COLLADA_ELEMENT_CLASS(ColladaLibraryArticulatedSystemsWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens an <articulated_system> element.
	ColladaArticulatedSystemWriter OpenArticulatedSystem();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaLibraryArticulatedSystemsWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<library_joints>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <library_joints> element.
COLLADA_ELEMENT_CLASS(ColladaLibraryJointsWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <joint> element.
	ColladaJointWriter OpenJoint();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaLibraryJointsWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<library_kinematics_models>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <library_kinematics_models> element.
COLLADA_ELEMENT_CLASS(ColladaLibraryKinematicsModelsWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <kinematics_model> element.
	ColladaKinematicsModelWriter OpenKinematicsModel();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaLibraryKinematicsModelsWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<library_kinematics_scenes>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <library_kinematics_scenes> element.
COLLADA_ELEMENT_CLASS(ColladaLibraryKinematicsScenesWriter)
{
public:
	// Sets the optional 'id' attribute value.
	COLLADA_DECLARE_SetID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <kinematics_scene> element.
	ColladaKinematicsSceneWriter OpenKinematicsScene();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaLibraryKinematicsScenesWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<link>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <link> element.
COLLADA_ELEMENT_CLASS(ColladaLinkWriter)
{
public:
	// Sets the optional 'sid' attribute value.
	COLLADA_DECLARE_SetSID;
	// Sets the optional 'name' attribute value.
	COLLADA_DECLARE_SetName;

	// Adds a <rotate> element.
	COLLADA_DECLARE_AddRotate;
	// Adds a <translate> element.
	COLLADA_DECLARE_AddTranslate;

	// Opens an <attachment_full> element.
	ColladaAttachmentFullWriter OpenAttachmentFull(const string& joint);
	// Opens an <attachment_start> element.
	ColladaAttachmentStartWriter OpenAttachmentStart(const string& joint);
	// Opens an <attachment_end> element.
	ColladaAttachmentEndWriter OpenAttachmentEnd(const string& joint);

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaLinkWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<motion>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <motion> element.
COLLADA_ELEMENT_CLASS(ColladaMotionWriter)
{
public:
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// TODO: <motion>

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaMotionWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<prismatic>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <prismatic> element.
COLLADA_ELEMENT_CLASS(ColladaPrismaticWriter)
{
public:
	// TODO: <prismatic>

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaPrismaticWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<revolute>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <revolute> element.
COLLADA_ELEMENT_CLASS(ColladaRevoluteWriter)
{
public:
	// TODO: <revolute>

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaRevoluteWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		<COLLADA>
// -------------------------------------------------------------------------------------------------------------------------------------

// Writes a <COLLADA> element.
COLLADA_ELEMENT_CLASS(ColladaCOLLADAWriter)
{
public:
	// Sets the optional 'xmlns' attribute value.
	void SetXmlNamespace(const string& value);
	// Sets the optional 'base' attribute value.
	void SetBase(const string& value);

	// Opens an <asset> element.
	COLLADA_DECLARE_OpenAsset;
	// Opens a <library_animation_clips> element.
	ColladaLibraryAnimationClipsWriter OpenLibraryAnimationClips();
	// Opens a <library_animations> element.
	ColladaLibraryAnimationsWriter OpenLibraryAnimations();
	// Opens a <library_articulated_systems> element.
	ColladaLibraryArticulatedSystemsWriter OpenLibraryArticulatedSystems();
	// Opens a <library_cameras> element.
	ColladaLibraryCamerasWriter OpenLibraryCameras();
	// Opens a <library_controllers> element.
	ColladaLibraryControllersWriter OpenLibraryControllers();
	// Opens a <library_effects> element.
	ColladaLibraryEffectsWriter OpenLibraryEffects();
	// Opens a <library_force_fields> element.
	ColladaLibraryForceFieldsWriter OpenLibraryForceFields();
	// Opens a <library_formulas> element.
	ColladaLibraryFormulasWriter OpenLibraryFormulas();
	// Opens a <library_geometries> element.
	ColladaLibraryGeometriesWriter OpenLibraryGeometries();
	// Opens a <library_images> element.
	ColladaLibraryImagesWriter OpenLibraryImages();
	// Opens a <library_joints> element.
	ColladaLibraryJointsWriter OpenLibraryJoints();
	// Opens a <library_kinematics_models> element.
	ColladaLibraryKinematicsModelsWriter OpenLibraryKinematicsModels();
	// Opens a <library_kinematics_scenes> element.
	ColladaLibraryKinematicsScenesWriter OpenLibraryKinematicsScenes();
	// Opens a <library_lights> element.
	ColladaLibraryLightsWriter OpenLibraryLights();
	// Opens a <library_materials> element.
	ColladaLibraryMaterialsWriter OpenLibraryMaterials();
	// Opens a <library_nodes> element.
	ColladaLibraryNodesWriter OpenLibraryNodes();
	// Opens a <library_physics_materials> element.
	ColladaLibraryPhysicsMaterialsWriter OpenLibraryPhysicsMaterials();
	// Opens a <library_physics_models> element.
	ColladaLibraryPhysicsModelsWriter OpenLibraryPhysicsModels();
	// Opens a <library_physics_scenes> element.
	ColladaLibraryPhysicsScenesWriter OpenLibraryPhysicsScenes();
	// Opens a <library_visual_scenes> element.
	ColladaLibraryVisualScenesWriter OpenLibraryVisualScenes();
	// Opens a <scene> element.
	ColladaSceneWriter OpenScene();
	// Opens an <extra> element.
	COLLADA_DECLARE_OpenExtra;

	// Constructor.
	COLLADA_ELEMENT_CTOR(ColladaCOLLADAWriter);
};

// -------------------------------------------------------------------------------------------------------------------------------------
//		File Writer
// -------------------------------------------------------------------------------------------------------------------------------------

// Represents an object that writes a COLLADA document to file.
class ColladaFileWriter sealed
{
public:
	// Constructor.
	ColladaFileWriter(ColladaVersion::Type version);

	// Sets the path to the file to write.
	//		path: the path to the file.
	//		returns: true on success, false otherwise.
	bool SetPath(const string& path);

	// Opens a <COLLADA> element.
	ColladaCOLLADAWriter OpenCOLLADA();

private:
	friend class ColladaElementWriter;

	ColladaVersion::Type	m_Version;
	XmlFileWriter			m_XmlWriter;
};
